author | kui.zhang <kui.zhang@amlogic.com> | 2012-09-08 08:33:36 (GMT) |
---|---|---|
committer | kui.zhang <kui.zhang@amlogic.com> | 2012-09-08 08:33:36 (GMT) |
commit | e38667e52d851e93009e73f45fb22e27bb4a5239 (patch) | |
tree | 46b97c7465dea194e70616531a815c5ad46ad3f4 | |
parent | 814f09a55b089fd6c6b45bb9162d6976887abdbc (diff) | |
download | libzvbi-e38667e52d851e93009e73f45fb22e27bb4a5239.zip libzvbi-e38667e52d851e93009e73f45fb22e27bb4a5239.tar.gz libzvbi-e38667e52d851e93009e73f45fb22e27bb4a5239.tar.bz2 |
add vbi demux,but have some error
-rwxr-xr-x | ntsc_decode/Android.mk | 14 | ||||
-rwxr-xr-x | ntsc_decode/am_ntsc_cc.c | 571 | ||||
-rwxr-xr-x | ntsc_decode/am_ntsc_cc.h | 66 | ||||
-rwxr-xr-x | ntsc_decode/caption.c | 943 | ||||
-rwxr-xr-x | ntsc_decode/caption.h | 34 | ||||
-rwxr-xr-x | ntsc_decode/decode.c | 11 | ||||
-rwxr-xr-x | ntsc_decode/decode.h | 40 | ||||
-rwxr-xr-x | ntsc_decode/ntsc_dmx/am_vbi_dmx.c | 708 | ||||
-rwxr-xr-x | ntsc_decode/ntsc_dmx/am_vbi_internal.h | 111 | ||||
-rwxr-xr-x | ntsc_decode/ntsc_dmx/include/vbi_dmx.h | 253 | ||||
-rwxr-xr-x | ntsc_decode/ntsc_dmx/linux_vbi/linux_ntsc.c | 309 | ||||
-rwxr-xr-x | ntsc_decode/ntsc_dmx/test/Android.mk | 17 | ||||
-rwxr-xr-x | ntsc_decode/ntsc_dmx/test/vbi_test.c | 209 | ||||
-rwxr-xr-x | ntsc_decode/test/Android.mk | 9 | ||||
-rwxr-xr-x | ntsc_decode/test/caption.c | 943 |
15 files changed, 4230 insertions, 8 deletions
diff --git a/ntsc_decode/Android.mk b/ntsc_decode/Android.mk index 9bdc56e..5820bba 100755 --- a/ntsc_decode/Android.mk +++ b/ntsc_decode/Android.mk @@ -1,13 +1,19 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) -LOCAL_SRC_FILES:=decode.c sliced1.c +LOCAL_SRC_FILES:=am_ntsc_cc.c \ + sliced1.c \ + ntsc_dmx/am_vbi_dmx.c \ + ntsc_dmx/linux_vbi/linux_ntsc.c + LOCAL_SHARED_LIBRARIES+= libzvbi LOCAL_C_INCLUDES:=$(LOCAL_PATH)/../src \ - $(LOCAL_PATH)/ - -LOCAL_MODULE:= ntsc_decode + $(LOCAL_PATH)/ \ + $(LOCAL_PATH)/ntsc_dmx/ \ + $(LOCAL_PATH)/ntsc_dmx/include + +LOCAL_MODULE:= libntsc_decode LOCAL_MODULE_TAGS := optional LOCAL_ARM_MODE := arm LOCAL_CFLAGS+=-D_REENTRANT -D_GNU_SOURCE -DENABLE_DVB=1 -DENABLE_V4L=1 -DENABLE_V4L2=1 -DHAVE_ICONV=1 -DPACKAGE=\"zvbi\" -DVERSION=\"0.2.33\" -DANDROID -DHAVE_GETOPT_LONG=1 diff --git a/ntsc_decode/am_ntsc_cc.c b/ntsc_decode/am_ntsc_cc.c new file mode 100755 index 0000000..5b94be5 --- a/dev/null +++ b/ntsc_decode/am_ntsc_cc.c @@ -0,0 +1,571 @@ +#undef NDEBUG + +#include <stdio.h> +#include <stdlib.h> +#include <pthread.h> +#include <unistd.h> +#include <string.h> + + + +#include "vbi.h" +#include "exp-gfx.h" +#include "hamm.h" +#include "dvb_demux.h" +#include "sliced.h" +#include "sliced1.h" +#include "am_ntsc_cc.h" + +typedef struct +{ + vbi_decoder *dec; + //vbi_search *search; + AM_NTSC_CC_Para_t para; + int page_no; + int sub_page_no; + vbi_bool disp_update; + vbi_bool running; + uint64_t pts; + pthread_mutex_t lock; + pthread_cond_t cond; + pthread_t thread; +}AM_NTSC_CC_Parser_t; + +/********************define variable***************************/ +#define XDS_SEP_DEBUG(x) /* x */ x + +vbi_pgno pgno = -1; +vbi_dvb_demux * dx; + +/* + * Rudimentary render code for CC test. + * Attention: RGB 5:6:5 little endian only. + */ + +#define DISP_WIDTH 640 +#define DISP_HEIGHT 480 + +#define CELL_WIDTH 16 +#define CELL_HEIGHT 26 +AM_NTSC_CC_Parser_t *parser; +uint32_t * ximgdata; +int shift = 0, step = 3; +int sh_first, sh_last; +vbi_rgba row_buffer[64 * CELL_WIDTH * CELL_HEIGHT]; +#define COLORKEY 0x80FF80 /* where video looks through */ + +#define RGB565(rgba) \ + (((((rgba) >> 16) & 0xF8) << 8) | ((((rgba) >> 8) & 0xFC) << 3) \ + | (((rgba) & 0xF8) >> 3)) + +/********************define function***************************/ + + static void +draw_blank (int column, + int width) +{ + vbi_rgba *canvas = row_buffer + column * CELL_WIDTH; + int x, y; + + for (y = 0; y < CELL_HEIGHT; y++) { + for (x = 0; x < CELL_WIDTH * width; x++) + canvas[x] = COLORKEY; + canvas += sizeof(row_buffer) / sizeof(row_buffer[0]) + / CELL_HEIGHT; + } +} + + + +static void +draw_row (uint32_t * canvas, + vbi_page * pg, + int row) +{ + int i, j, num_tspaces = 0; + vbi_rgba *s = row_buffer; + XDS_SEP_DEBUG(printf("draw_row = %d\n",row)); + for (i = 0; i < pg->columns; ++i) { + XDS_SEP_DEBUG(printf("%02x ", pg->text[row * pg->columns + i].unicode)); + if (pg->text[row * pg->columns + i].opacity + == VBI_TRANSPARENT_SPACE) { + num_tspaces++; + continue; + } + if (num_tspaces > 0) { + draw_blank(i - num_tspaces, num_tspaces); + num_tspaces = 0; + } + + // vbi_draw_cc_page_region (pg, VBI_PIXFMT_RGBA32_LE, + // row_buffer + i * CELL_WIDTH, + // sizeof(row_buffer) / CELL_HEIGHT, + // i, row, 1, 1); + + vbi_draw_cc_page_region (pg, VBI_PIXFMT_RGBA32_LE, + parser->para.bitmap + i * CELL_WIDTH, + sizeof(row_buffer) / CELL_HEIGHT, + i, row, 1, 1); + } + + if (num_tspaces > 0) + draw_blank(i - num_tspaces, num_tspaces); + + XDS_SEP_DEBUG(printf("\npg->columns * CELL_WIDTH= %d\n",pg->columns * CELL_WIDTH)); + return; + for (i = 0; i < CELL_HEIGHT; i++) { + for (j = 0; j < pg->columns * CELL_WIDTH; j++){ + canvas[j] = RGB565(s[j]); + } + s += sizeof(row_buffer) / sizeof(row_buffer[0]) / CELL_HEIGHT; + + canvas += DISP_WIDTH; + } +} + +static void +bump (int n, + vbi_bool draw) +{ + uint32_t *canvas = ximgdata + 45 * DISP_WIDTH; + XDS_SEP_DEBUG(printf("bump")); + return; + if (shift < n) + n = shift; + + if (shift <= 0 || n <= 0) + return; + + memmove (canvas + (sh_first * CELL_HEIGHT) * DISP_WIDTH, + canvas + (sh_first * CELL_HEIGHT + n) * DISP_WIDTH, + ((sh_last - sh_first + 1) * CELL_HEIGHT - n) + * DISP_WIDTH * 2); + + //if (draw) + // XPutImage (display, window, gc, ximage, + // 0, 0, 0, 0, DISP_WIDTH, DISP_HEIGHT); + + shift -= n; +} + + + +static void +render (vbi_page * pg, + int row) +{ + //* ushort *canvas = ximgdata + 48 + 45 * DISP_WIDTH; + XDS_SEP_DEBUG(printf("render row %d\n",row)); + if (shift > 0) { + bump(shift, FALSE); + //draw_video (48, 45 + sh_last * CELL_HEIGHT, + // DISP_WIDTH - 48, CELL_HEIGHT); + } + XDS_SEP_DEBUG(printf("render draw_row %d\n",ximgdata + 48 + (45 + row * CELL_HEIGHT) * DISP_WIDTH)); + + if(parser->para.draw_begin) + parser->para.draw_begin(parser); + draw_row (ximgdata + 48 + (45 + row * CELL_HEIGHT) * DISP_WIDTH, + pg, row); + if(parser->para.draw_end) + parser->para.draw_end(parser); + + //XPutImage (display, window, gc, ximage, + // 0, 0, 0, 0, DISP_WIDTH, DISP_HEIGHT); +} + + +static void NTSC_CC_show(AM_NTSC_CC_Parser_t *parser) +{ + vbi_page page; + vbi_bool cached; + + //cached = vbi_fetch_vt_page(parser->dec, &page, vbi_dec2bcd(parser->page_no), parser->sub_page_no, VBI_WST_LEVEL_3p5, 25, AM_TRUE); + //if(!cached) + // return; + + //parser->sub_page_no = page.subno; + + //if(parser->para.draw_begin) + // parser->para.draw_begin(parser); + + /*{ + char buf[256]; + int i, j; + + for(i=0; i<page.rows; i++){ + char *ptr = buf; + for(j=0; j<page.columns; j++){ + sprintf(ptr, "%02x", page.text[i*page.columns+j].unicode); + ptr += 2; + } + + AM_DEBUG(1, "text %02d: %s", i, buf); + } + }*/ + + //vbi_draw_vt_page_region(&page, VBI_PIXFMT_RGBA32_LE, parser->para.bitmap, parser->para.pitch, + // 0, 0, page.columns, page.rows, 1, 1, parser->para.is_subtitle); + + //if(parser->para.draw_end) + // parser->para.draw_end(parser); + + //vbi_unref_page(&page); +} + + + + + + + + + + + +static void +reset (void) +{ + vbi_page page; + vbi_bool success; + int row; + + success = vbi_fetch_cc_page (parser->dec, &page, pgno, TRUE); + assert (success); + + for (row = 0; row <= page.rows; ++row) + render (&page, row); + + vbi_unref_page (&page); +} + +/**********************************************************/ +static void* ntsc_cc_thread(void *arg) +{ + AM_NTSC_CC_Parser_t *parser = (AM_NTSC_CC_Parser_t*)arg; + + pthread_mutex_lock(&parser->lock); + + while(parser->running) + { + while(parser->running && !parser->disp_update){ + pthread_cond_wait(&parser->cond, &parser->lock); + } + + if(parser->disp_update){ + ntsc_cc_show(parser); + parser->disp_update = FALSE; + } + } + + pthread_mutex_unlock(&parser->lock); + + return NULL; +} + + + void ntsc_cc_show(AM_NTSC_CC_Parser_t *parser) +{ + vbi_page page; + vbi_bool success; + int row; + vbi_event * ev; + //user_data = user_data; + + if (pgno != -1 && ev->ev.caption.pgno != pgno) + return; + + /* Fetching & rendering in the handler + is a bad idea, but this is only a test */ + + success = vbi_fetch_cc_page (parser->dec, &page, ev->ev.caption.pgno, TRUE); + assert (success); + + if(parser->para.draw_begin) + parser->para.draw_begin(parser); + + for (row = page.dirty.y0; row <= page.dirty.y1; ++row) + render (&page, row); + + if(parser->para.draw_end) + parser->para.draw_end(parser); + vbi_unref_page (&page); +} +/**********************************************************/ +static void +cc_handler (vbi_event * ev, + void * user_data) +{ + + printf("cc_handler\n"); + vbi_page page; + vbi_bool success; + int row; + + user_data = user_data; + + if (pgno != -1 && ev->ev.caption.pgno != pgno) + return; + + /* Fetching & rendering in the handler + is a bad idea, but this is only a test */ + + success = vbi_fetch_cc_page (parser->dec, &page, ev->ev.caption.pgno, TRUE); + assert (success); + XDS_SEP_DEBUG(printf("cc_handler***********success = %d\n",success)); +#if 1 /* optional */ + if (abs (page.dirty.roll) > page.rows) { + XDS_SEP_DEBUG(printf("clear")); + //clear (&page); + } else if (page.dirty.roll == -1) { + XDS_SEP_DEBUG(printf("roll_up")); + //roll_up (&page, page.dirty.y0, page.dirty.y1); + } else { +#endif + for (row = page.dirty.y0; row <= page.dirty.y1; ++row) + render (&page, row); + } + vbi_unref_page (&page); +} + + + + +static vbi_bool +decode_frame (const vbi_sliced * sliced, + unsigned int n_lines, + const uint8_t * raw, + const vbi_sampling_par *sp, + double sample_time, + int64_t stream_time) +{ + printf("decode_frame\n"); + raw = raw; + sp = sp; + stream_time = stream_time; /* unused */ + + vbi_decode (parser->dec, sliced, n_lines, sample_time); + + /* xevent (1e6 / 30); */ + + return TRUE; +} + + + vbi_bool AM_NTSC_Create(AM_NTSC_CC_Handle_t *handle, AM_NTSC_CC_Para_t *para) +{ + if(!para || !handle) + { + return FALSE; + } + parser = (AM_NTSC_CC_Parser_t*)malloc(sizeof(AM_NTSC_CC_Parser_t)); + if(!parser) + { + return FALSE; + } + + vbi_bool success; + parser->dec = vbi_decoder_new (); + assert (NULL != parser->dec); + success = vbi_event_handler_add (parser->dec, VBI_EVENT_CAPTION, + cc_handler, /* used_data */ NULL); + assert (success); + pthread_mutex_init(&parser->lock, NULL); + pthread_cond_init(&parser->cond, NULL); + + *handle = parser; + parser->para = *para; + return TRUE; +} + + + vbi_bool AM_NTSC_CC_Start(AM_NTSC_CC_Handle_t handle) +{ + __android_log_print(ANDROID_LOG_INFO, "NTSC_CC", "AM_NTSC_CC_Start"); + AM_NTSC_CC_Parser_t *parser = (AM_NTSC_CC_Para_t*)handle; + unsigned char pBuffer[] ={ + 0x00,0x01,0x02,0x00,0x15,0x00,0x00,0x00, + 0x00,0x01,0x02,0x00,0x15,0x00,0x01,0x05, + 0x00,0x01,0x02,0x00,0x15,0x00,0x41,0x40, + 0x00,0x01,0x02,0x00,0x15,0x00,0x0f,0x6a, + 0x00,0x01,0x02,0x00,0x15,0x00,0x00,0x00, + 0x00,0x01,0x02,0x00,0x15,0x00,0x00,0x00, + 0x00,0x01,0x02,0x00,0x15,0x00,0x15,0x2c, + 0x00,0x01,0x02,0x00,0x15,0x00,0x15,0x2e, + 0x00,0x01,0x02,0x00,0x15,0x00,0x15,0x20, + 0x00,0x01,0x02,0x00,0x15,0x00,0x16,0x46, + 0x00,0x01,0x02,0x00,0x15,0x00,0x20,0x20, + 0x00,0x01,0x02,0x00,0x15,0x00,0x10,0x22, + 0x00,0x01,0x02,0x00,0x15,0x00,0x43,0x6c, + 0x00,0x01,0x02,0x00,0x15,0x00,0x6f,0x73, + 0x00,0x01,0x02,0x00,0x15,0x00,0x65,0x64, + 0x00,0x01,0x02,0x00,0x15,0x00,0x20,0x43, + 0x00,0x01,0x02,0x00,0x15,0x00,0x61,0x70, + 0x00,0x01,0x02,0x00,0x15,0x00,0x74,0x69, + 0x00,0x01,0x02,0x00,0x15,0x00,0x6f,0x6e , + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x2f, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x41,0x00, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x45,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x4f,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x75,0x00, + + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x2f, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x41,0x00, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x45,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x4f,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x75,0x00, + + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x2f, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x41,0x00, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x45,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x4f,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x75,0x00, + + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x2f, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x41,0x00, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x45,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x4f,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x75,0x00, + }; + int length = N_ELEMENTS (pBuffer); + struct stream *st; + st = read_stream_new (pBuffer,length, + FILE_FORMAT_SLICED, + 0, + decode_frame); + + //st = read_stream_new (/* filename: stdin */ NULL, + // FILE_FORMAT_SLICED, + // /* ts_pid */ 0, + // decode_frame); + //if(parser->para.draw_begin) + // parser->para.draw_begin(parser); + + stream_loop (st); + + //if(parser->para.draw_end) + // parser->para.draw_end(parser); + + stream_delete (st); + //} + + printf ("Done.\n"); + + //for (;;) + // xevent (33333); + + vbi_decoder_delete (parser->dec); + + + /* + vbi_bool ret = AM_SUCCESS; + + if(!parser) + { + return AM_TT2_ERR_INVALID_HANDLE; + } + + pthread_mutex_lock(&parser->lock); + + if(!parser->running) + { + parser->running = AM_TRUE; + if(pthread_create(&parser->thread, NULL, tt2_thread, parser)) + { + parser->running = AM_FALSE; + ret = AM_TT2_ERR_CANNOT_CREATE_THREAD; + } + } + + pthread_mutex_unlock(&parser->lock); +*/ + + + return TRUE; +} + + diff --git a/ntsc_decode/am_ntsc_cc.h b/ntsc_decode/am_ntsc_cc.h new file mode 100755 index 0000000..a474db5 --- a/dev/null +++ b/ntsc_decode/am_ntsc_cc.h @@ -0,0 +1,66 @@ +/*************************************************************************** + * Copyright C 2009 by Amlogic, Inc. All Rights Reserved. + */ +/**\file + * \brief Teletext模块(version 2) + * + * \author kui.zhang <kui.zhang@amlogic.com> + * \date 2012-09-03: create the document + ***************************************************************************/ + + + +#ifndef _AM_NTSC_CC_H +#define _AM_NTSC_CC_H + + +#include <unistd.h> +#include "misc.h" +#include "trigger.h" +#include "format.h" +#include "lang.h" +#include "hamm.h" +#include "tables.h" +#include "vbi.h" +#include <android/log.h> +#ifdef __cplusplus +extern "C" +{ +#endif + +/**************************************************************************** + * Type definitions + ***************************************************************************/ + /**\brief Teletext分析器句柄*/ +typedef void* AM_NTSC_CC_Handle_t; + +/**\brief 开始绘制*/ +typedef void (*AM_TT2_DrawBegin_t)(AM_NTSC_CC_Handle_t handle); + +/**\brief 结束绘制*/ +typedef void (*AM_TT2_DrawEnd_t)(AM_NTSC_CC_Handle_t handle); + + typedef struct +{ + AM_TT2_DrawBegin_t draw_begin; /**< 开始绘制*/ + AM_TT2_DrawEnd_t draw_end; /**< 结束绘制*/ + vbi_bool is_subtitle; /**< 是否为字幕*/ + uint8_t *bitmap; /**< 绘图缓冲区*/ + int pitch; /**< 绘图缓冲区每行字节数*/ + void *user_data; /**< 用户定义数据*/ +}AM_NTSC_CC_Para_t; + + +extern vbi_bool AM_NTSC_Create(AM_NTSC_CC_Handle_t *handle, AM_NTSC_CC_Para_t *para); + +extern vbi_bool AM_NTSC_CC_Start(AM_NTSC_CC_Handle_t handle); + + + +#ifdef __cplusplus +} +#endif + + + +#endif diff --git a/ntsc_decode/caption.c b/ntsc_decode/caption.c new file mode 100755 index 0000000..def1f99 --- a/dev/null +++ b/ntsc_decode/caption.c @@ -0,0 +1,943 @@ +/* + * libzvbi test + * + * Copyright (C) 2000, 2001 Michael H. Schimek + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +/* $Id: caption.c,v 1.19 2008/03/01 07:37:20 mschimek Exp $ */ + +#undef NDEBUG + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <unistd.h> + +#ifndef X_DISPLAY_MISSING + +//#include <X11/Xlib.h> +//#include <X11/keysym.h> +//#include <X11/Xutil.h> + +#include "vbi.h" +#include "exp-gfx.h" +#include "hamm.h" +#include "dvb_demux.h" +#include "sliced.h" +#include "sliced1.h" +#define XDS_SEP_DEBUG(x) /* x */ x +vbi_decoder * vbi; +vbi_pgno pgno = -1; +vbi_dvb_demux * dx; + +/* + * Rudimentary render code for CC test. + * Attention: RGB 5:6:5 little endian only. + */ + +#define DISP_WIDTH 640 +#define DISP_HEIGHT 480 + +#define CELL_WIDTH 16 +#define CELL_HEIGHT 26 + +//Display * display; +int screen; +//Colormap cmap; +//Window window; +//GC gc; +//XEvent event; +//XImage * ximage; +uint32_t * ximgdata; + +int shift = 0, step = 3; +int sh_first, sh_last; + +vbi_rgba row_buffer[64 * CELL_WIDTH * CELL_HEIGHT]; + +#define COLORKEY 0x80FF80 /* where video looks through */ + +#define RGB565(rgba) \ + (((((rgba) >> 16) & 0xF8) << 8) | ((((rgba) >> 8) & 0xFC) << 3) \ + | (((rgba) & 0xF8) >> 3)) + +static void +draw_video (int x0, + int y0, + int w, + int h) +{ + uint32_t *canvas = ximgdata + x0 + y0 * DISP_WIDTH; + int x, y; + + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) + canvas[x] = RGB565(COLORKEY); + canvas += DISP_WIDTH; + } +} + +static void +draw_blank (int column, + int width) +{ + vbi_rgba *canvas = row_buffer + column * CELL_WIDTH; + int x, y; + + for (y = 0; y < CELL_HEIGHT; y++) { + for (x = 0; x < CELL_WIDTH * width; x++) + canvas[x] = COLORKEY; + canvas += sizeof(row_buffer) / sizeof(row_buffer[0]) + / CELL_HEIGHT; + } +} + +//* Not exactly efficient, but this is only a test +static void +draw_row (uint32_t * canvas, + vbi_page * pg, + int row) +{ + int i, j, num_tspaces = 0; + vbi_rgba *s = row_buffer; + XDS_SEP_DEBUG(printf("draw_row = %d\n",row)); + for (i = 0; i < pg->columns; ++i) { + XDS_SEP_DEBUG(printf("%02x ", unicode_ccfont2 (pg->text[row * pg->columns + i].unicode, pg->text[row * pg->columns + i].->italic))); + if (pg->text[row * pg->columns + i].opacity + == VBI_TRANSPARENT_SPACE) { + num_tspaces++; + continue; + } + + if (num_tspaces > 0) { + draw_blank(i - num_tspaces, num_tspaces); + num_tspaces = 0; + } + + vbi_draw_cc_page_region (pg, VBI_PIXFMT_RGBA32_LE, + row_buffer + i * CELL_WIDTH, + sizeof(row_buffer) / CELL_HEIGHT, + i, row, 1, 1); + } + + if (num_tspaces > 0) + draw_blank(i - num_tspaces, num_tspaces); + + XDS_SEP_DEBUG(printf("\npg->columns * CELL_WIDTH= %d\n",pg->columns * CELL_WIDTH)); + return; + for (i = 0; i < CELL_HEIGHT; i++) { + for (j = 0; j < pg->columns * CELL_WIDTH; j++){ + canvas[j] = RGB565(s[j]); + } + s += sizeof(row_buffer) / sizeof(row_buffer[0]) / CELL_HEIGHT; + + canvas += DISP_WIDTH; + } +} + +static void +bump (int n, + vbi_bool draw) +{ + uint32_t *canvas = ximgdata + 45 * DISP_WIDTH; + XDS_SEP_DEBUG(printf("bump")); + return; + if (shift < n) + n = shift; + + if (shift <= 0 || n <= 0) + return; + + memmove (canvas + (sh_first * CELL_HEIGHT) * DISP_WIDTH, + canvas + (sh_first * CELL_HEIGHT + n) * DISP_WIDTH, + ((sh_last - sh_first + 1) * CELL_HEIGHT - n) + * DISP_WIDTH * 2); + + //if (draw) + // XPutImage (display, window, gc, ximage, + // 0, 0, 0, 0, DISP_WIDTH, DISP_HEIGHT); + + shift -= n; +} + +static void +render (vbi_page * pg, + int row) +{ + //* ushort *canvas = ximgdata + 48 + 45 * DISP_WIDTH; + XDS_SEP_DEBUG(printf("render row %d\n",row)); + if (shift > 0) { + bump(shift, FALSE); + draw_video (48, 45 + sh_last * CELL_HEIGHT, + DISP_WIDTH - 48, CELL_HEIGHT); + } + XDS_SEP_DEBUG(printf("render draw_row %d\n",ximgdata + 48 + (45 + row * CELL_HEIGHT) * DISP_WIDTH)); + draw_row (ximgdata + 48 + (45 + row * CELL_HEIGHT) * DISP_WIDTH, + pg, row); + + //XPutImage (display, window, gc, ximage, + // 0, 0, 0, 0, DISP_WIDTH, DISP_HEIGHT); +} +/* +static void +clear (vbi_page * pg) +{ + pg = pg; + + draw_video (0, 0, DISP_WIDTH, DISP_HEIGHT); + + XPutImage (display, window, gc, ximage, + 0, 0, 0, 0, DISP_WIDTH, DISP_HEIGHT); +} + +static void +roll_up (vbi_page * pg, + int first_row, + int last_row) +{ + ushort scol, *canvas = ximgdata + 45 * DISP_WIDTH; + vbi_rgba col; + int i, j; + +#if 1 //* soft + + sh_first = first_row; + sh_last = last_row; + shift = 26; + bump(step, FALSE); + + canvas += 48 + (((last_row * CELL_HEIGHT) + CELL_HEIGHT - step) + * DISP_WIDTH); + col = pg->color_map[pg->text[last_row * pg->columns].background]; + scol = RGB565 (col); + + for (j = 0; j < step; ++j) { + if (pg->text[last_row * pg->columns].opacity + == VBI_TRANSPARENT_SPACE) { + for (i = 0; i < CELL_WIDTH * pg->columns; ++i) + canvas[i] = RGB565 (COLORKEY); + } else { + for (i = 0; i < CELL_WIDTH * pg->columns; ++i) + canvas[i] = scol; + } + + canvas += DISP_WIDTH; + } + +#else //* at once + + memmove (canvas + first_row * CELL_HEIGHT * DISP_WIDTH, + canvas + (first_row + 1) * CELL_HEIGHT * DISP_WIDTH, + (last_row - first_row) * CELL_HEIGHT * DISP_WIDTH * 2); + + draw_video (48, 45 + last_row * CELL_HEIGHT, + DISP_WIDTH - 48, CELL_HEIGHT); + +#endif + + XPutImage (display, window, gc, ximage, + 0, 0, 0, 0, DISP_WIDTH, DISP_HEIGHT); +} + +static void +xevent (int nap_usec); +*/ +static void +cc_handler (vbi_event * ev, + void * user_data) +{ + + printf("cc_handler\n"); + vbi_page page; + vbi_bool success; + int row; + + user_data = user_data; + + if (pgno != -1 && ev->ev.caption.pgno != pgno) + return; + + /* Fetching & rendering in the handler + is a bad idea, but this is only a test */ + + success = vbi_fetch_cc_page (vbi, &page, ev->ev.caption.pgno, TRUE); + assert (success); + XDS_SEP_DEBUG(printf("cc_handler***********success = %d\n",success)); +#if 1 /* optional */ + if (abs (page.dirty.roll) > page.rows) { + XDS_SEP_DEBUG(printf("clear")); + //clear (&page); + } else if (page.dirty.roll == -1) { + XDS_SEP_DEBUG(printf("roll_up")); + //roll_up (&page, page.dirty.y0, page.dirty.y1); + } else { +#endif + + for (row = page.dirty.y0; row <= page.dirty.y1; ++row) + render (&page, row); + } + + vbi_unref_page (&page); +} + + + + + + + + + +static void +xds_handler (vbi_event * ev, + void * user_data) +{ + + printf("xds_handler\n"); + vbi_page page; + vbi_bool success; + if(ev == NULL) + return; + + + vbi_program_info * prog_info = ev->ev.prog_info; + + if(prog_info->rating_auth != VBI_RATING_AUTH_NONE) + { + printf("prog_info->rating_auth = %d\n",prog_info->rating_auth ); + + if(prog_info->rating_auth == VBI_RATING_AUTH_MPAA) + XDS_SEP_DEBUG(printf("result*******************VBI_RATING_AUTH_MPAA\n")); + if(prog_info->rating_auth == VBI_RATING_AUTH_TV_US) + XDS_SEP_DEBUG(printf("result*******************VBI_RATING_AUTH_TV_US\n")); + if(prog_info->rating_auth == VBI_RATING_AUTH_TV_CA_EN) + XDS_SEP_DEBUG(printf("result*******************VBI_RATING_AUTH_TV_CA_EN\n")); + if(prog_info->rating_auth == VBI_RATING_AUTH_TV_CA_FR) + XDS_SEP_DEBUG(printf("result*******************VBI_RATING_AUTH_TV_CA_FR\n")); + if(prog_info->rating_auth == VBI_RATING_AUTH_NONE) + XDS_SEP_DEBUG(printf("result*******************VBI_RATING_AUTH_NONE\n")); + + if (prog_info->rating_dlsv == VBI_RATING_D) + XDS_SEP_DEBUG(printf("result*******************VBI_RATING_D\n")); + if (prog_info->rating_dlsv == VBI_RATING_L) + XDS_SEP_DEBUG(printf("result*******************VBI_RATING_L\n")); + if (prog_info->rating_dlsv == VBI_RATING_S) + XDS_SEP_DEBUG(printf("result*******************VBI_RATING_S\n")); + if (prog_info->rating_dlsv == VBI_RATING_V) + XDS_SEP_DEBUG(printf("result*******************VBI_RATING_V\n")); + XDS_SEP_DEBUG(printf("result*******************prog_info->rating_id = %d\n",prog_info->rating_id )); + + } + +} + + + +static void +reset (void) +{ + vbi_page page; + vbi_bool success; + int row; + + success = vbi_fetch_cc_page (vbi, &page, pgno, TRUE); + assert (success); + + for (row = 0; row <= page.rows; ++row) + render (&page, row); + + vbi_unref_page (&page); +} + +/* + * X11 stuff + */ +/* +static void +xevent (int nap_usec) +{ + while (XPending (display)) { + XNextEvent (display, &event); + + switch (event.type) { + case KeyPress: + { + int c = XLookupKeysym (&event.xkey, 0); + + switch (c) { + case 'q': + case 'c': + exit (EXIT_SUCCESS); + + case '1' ... '8': + pgno = c - '1' + 1; + reset (); + return; + + case XK_F1 ... XK_F8: + pgno = c - XK_F1 + 1; + reset (); + return; + } + + break; + } + + case Expose: + XPutImage (display, window, gc, ximage, + 0, 0, 0, 0, DISP_WIDTH, DISP_HEIGHT); + break; + + case ClientMessage: + exit (EXIT_SUCCESS); + } + } + + bump (step, TRUE); + + usleep (nap_usec / 4); +} +*/ +static vbi_bool +init_window (int ac, + char ** av) +{ + //Atom delete_window_atom; + //XWindowAttributes wa; + int i; + + ac = ac; + av = av; + + //if (!(display = XOpenDisplay (NULL))) { + // return FALSE; + //} + + //screen = DefaultScreen (display); + //cmap = DefaultColormap (display, screen); + + //window = XCreateSimpleWindow (display, + // RootWindow (display, screen), + // 0, 0, + // DISP_WIDTH, DISP_HEIGHT, + // 2, + // 0xffffffff, + // 0x00000000); + //if (!window) { + // return FALSE; + //} + + //XGetWindowAttributes (display, window, &wa); + + //if (16 != wa.depth) { + // fprintf (stderr, "Can only run at " + // "color depth 16 (5:6:5) LE\n"); + // return FALSE; + //} + + if (!(ximgdata = malloc (DISP_WIDTH * DISP_HEIGHT * 2))) { + return FALSE; + } + + for (i = 0; i < DISP_WIDTH * DISP_HEIGHT; ++i) + ximgdata[i] = RGB565 (COLORKEY); + + //ximage = XCreateImage(display, + // DefaultVisual (display, screen), + // DefaultDepth (display, screen), + // ZPixmap, 0, (char *) ximgdata, + // DISP_WIDTH, DISP_HEIGHT, + // 8, 0); + //if (!ximage) { + // return FALSE; + //} + + //delete_window_atom = XInternAtom (display, "WM_DELETE_WINDOW", False); + + //XSelectInput (display, window, + // KeyPressMask | + // ExposureMask | + // StructureNotifyMask); + //XSetWMProtocols (display, window, &delete_window_atom, 1); + //XStoreName (display, window, "Caption Test - [Q], [F1]..[F8]"); + + //gc = XCreateGC (display, window, 0, NULL); + + //XMapWindow (display, window); + + //XSync (display, False); + + //XPutImage (display, window, gc, ximage, + // 0, 0, 0, 0, DISP_WIDTH, DISP_HEIGHT); + + return TRUE; +} + +static vbi_bool +decode_frame (const vbi_sliced * sliced, + unsigned int n_lines, + const uint8_t * raw, + const vbi_sampling_par *sp, + double sample_time, + int64_t stream_time) +{ + printf("decode_frame\n"); + raw = raw; + sp = sp; + stream_time = stream_time; /* unused */ + + vbi_decode (vbi, sliced, n_lines, sample_time); + + /* xevent (1e6 / 30); */ + + return TRUE; +} + +/* + * Feed artificial caption + */ + +static void +cmd (unsigned int n) +{ + vbi_sliced sliced; + static double time = 0.0; + + sliced.id = VBI_SLICED_CAPTION_525; + sliced.line = 21; + sliced.data[0] = vbi_par8 (n >> 8); + sliced.data[1] = vbi_par8 (n & 0x7F); + + vbi_decode (vbi, &sliced, 1, time); + + //xevent (33333); + + time += 1 / 29.97; +} + +static void +printc (int c) +{ + cmd (c * 256 + 0x80); + + //xevent (33333); +} + +static void +prints (const char * s) +{ + for (; s[0] && s[1]; s += 2) + cmd (s[0] * 256 + s[1]); + + if (s[0]) + cmd (s[0] * 256 + 0x80); + + //xevent (33333); +} + +enum { + white, green, red, yellow, blue, cyan, magenta, black +}; + +static int +mapping_row [] = { + 2, 3, 4, 5, 10, 11, 12, 13, 14, 15, 0, 6, 7, 8, 9, -1 +}; + +#define italic 7 +#define underline 1 +#define opaque 0 +#define semi_transp 1 + +#define BACKG(bg, t) \ + (cmd (0x2000), cmd (0x1020 + ((ch & 1) << 11) + (bg << 1) + t)) +#define PREAMBLE(r, fg, u) \ + cmd (0x1040 + ((ch & 1) << 11) + ((mapping_row[r] & 14) << 7) \ + + ((mapping_row[r] & 1) << 5) + (fg << 1) + u) +#define INDENT(r, fg, u) \ + cmd (0x1050 + ((ch & 1) << 11) + ((mapping_row[r] & 14) << 7) \ + + ((mapping_row[r] & 1) << 5) + ((fg / 4) << 1) + u) +#define MIDROW(fg, u) cmd (0x1120 + ((ch & 1) << 11) + (fg << 1) + u) +#define SPECIAL_CHAR(n) cmd (0x1130 + ((ch & 1) << 11) + n) +#define CCODE(code, ch) (code + ((ch & 1) << 11) + ((ch & 2) << 7)) +#define RESUME_CAPTION cmd (CCODE (0x1420, ch)) +#define BACKSPACE cmd (CCODE (0x1421, ch)) +#define DELETE_EOR cmd (CCODE (0x1424, ch)) +#define ROLL_UP(rows) cmd (CCODE (0x1425, ch) + rows - 2) +#define FLASH_ON cmd (CCODE (0x1428, ch)) +#define RESUME_DIRECT cmd (CCODE (0x1429, ch)) +#define TEXT_RESTART cmd (CCODE (0x142A, ch)) +#define RESUME_TEXT cmd (CCODE (0x142B, ch)) +#define END_OF_CAPTION cmd (CCODE (0x142F, ch)) +#define ERASE_DISPLAY cmd (CCODE (0x142C, ch)) +#define CR cmd (CCODE (0x142D, ch)) +#define ERASE_HIDDEN cmd (CCODE (0x142E, ch)) +#define TAB(t) cmd (CCODE (0x1720, ch) + t) +#define TRANSP (cmd (0x2000), cmd (0x172D + ((ch & 1) << 11))) +#define BLACK(u) (cmd (0x2000), cmd (0x172E + ((ch & 1) << 11) + u)) + +static void +PAUSE (unsigned int n_frames) +{ + while (n_frames-- > 0){ + //xevent (33333); + } +} + +static void +hello_world (void) +{ + int ch = 0; + int i; + + pgno = -1; + + prints (" HELLO WORLD! "); + PAUSE (30); + + ch = 4; + TEXT_RESTART; + prints ("Character set - Text 1"); + CR; CR; + for (i = 32; i <= 127; i++) { + printc (i); + if ((i & 15) == 15) + CR; + } + MIDROW (italic, 0); + for (i = 32; i <= 127; i++) { + printc (i); + if ((i & 15) == 15) + CR; + } + MIDROW (white, underline); + for (i = 32; i <= 127; i++) { + printc (i); + if ((i & 15) == 15) + CR; + } + MIDROW (white, 0); + prints ("Special: "); + for (i = 0; i <= 15; i++) { + SPECIAL_CHAR (i); + } + CR; + prints ("DONE - Text 1 "); + PAUSE (50); + + ch = 5; + TEXT_RESTART; + prints ("Styles - Text 2"); + CR; CR; + MIDROW (white, 0); prints ("WHITE"); CR; + MIDROW (red, 0); prints ("RED"); CR; + MIDROW (green, 0); prints ("GREEN"); CR; + MIDROW (blue, 0); prints ("BLUE"); CR; + MIDROW (yellow, 0); prints ("YELLOW"); CR; + MIDROW (cyan, 0); prints ("CYAN"); CR; + MIDROW (magenta, 0); prints ("MAGENTA"); BLACK (0); CR; + BACKG (white, opaque); prints ("WHITE"); BACKG (black, opaque); CR; + BACKG (red, opaque); prints ("RED"); BACKG (black, opaque); CR; + BACKG (green, opaque); prints ("GREEN"); BACKG (black, opaque); CR; + BACKG (blue, opaque); prints ("BLUE"); BACKG (black, opaque); CR; + BACKG (yellow, opaque); prints ("YELLOW"); BACKG (black, opaque); CR; + BACKG (cyan, opaque); prints ("CYAN"); BACKG (black, opaque); CR; + BACKG (magenta, opaque); prints ("MAGENTA"); BACKG (black, opaque); CR; + TRANSP; + prints (" TRANSPARENT BACKGROUND "); + BACKG (black, opaque); CR; + MIDROW (white, 0); FLASH_ON; + prints (" Flashing Text (if implemented) "); CR; + MIDROW (white, 0); prints ("DONE - Text 2 "); + PAUSE (50); + + ch = 0; + ROLL_UP (2); + ERASE_DISPLAY; + prints (" ROLL-UP TEST "); CR; PAUSE (20); + prints (">> A young Jedi named Darth"); CR; PAUSE (20); + prints ("Vader, who was a pupil of"); CR; PAUSE (20); + prints ("mine until he turned to evil,"); CR; PAUSE (20); + prints ("helped the Empire hunt down"); CR; PAUSE (20); + prints ("and destroy the Jedi Knights."); CR; PAUSE (20); + prints ("He betrayed and murdered your"); CR; PAUSE (20); + prints ("father. Now the Jedi are all"); CR; PAUSE (20); + prints ("but extinct. Vader was seduced"); CR; PAUSE (20); + prints ("by the dark side of the Force."); CR; PAUSE (20); + prints (">> The Force?"); CR; PAUSE (20); + prints (">> Well, the Force is what gives"); CR; PAUSE (20); + prints ("a Jedi his power. It's an energy"); CR; PAUSE (20); + prints ("field created by all living"); CR; PAUSE (20); + prints ("things."); CR; PAUSE (20); + prints ("It surrounds us and penetrates"); CR; PAUSE (20); + prints ("us."); CR; PAUSE (20); + prints ("It binds the galaxy together."); CR; PAUSE (20); + CR; PAUSE (30); + prints (" DONE - Caption 1 "); + PAUSE (30); + + ch = 1; + RESUME_DIRECT; + ERASE_DISPLAY; + MIDROW (yellow, 0); + INDENT (2, 10, 0); prints (" FOO "); CR; + INDENT (3, 10, 0); prints (" MIKE WAS HERE "); CR; PAUSE (20); + MIDROW (red, 0); + INDENT (6, 13, 0); prints (" AND NOW... "); CR; + INDENT (8, 13, 0); prints (" HE'S HERE "); CR; PAUSE (20); + PREAMBLE (12, cyan, 0); + prints ("01234567890123456789012345678901234567890123456789"); CR; + MIDROW (white, 0); + prints (" DONE - Caption 2 "); CR; + PAUSE (30); +} + +int +main (int argc, + char ** argv) +{ + + unsigned char pBuffer[] ={ + 0x00,0x01,0x02,0x00,0x15,0x00,0x00,0x00, + 0x00,0x01,0x02,0x00,0x15,0x00,0x01,0x05, + 0x00,0x01,0x02,0x00,0x15,0x00,0x41,0x40, + 0x00,0x01,0x02,0x00,0x15,0x00,0x0f,0x6a, + 0x00,0x01,0x02,0x00,0x15,0x00,0x00,0x00, + 0x00,0x01,0x02,0x00,0x15,0x00,0x00,0x00, + 0x00,0x01,0x02,0x00,0x15,0x00,0x15,0x2c, + 0x00,0x01,0x02,0x00,0x15,0x00,0x15,0x2e, + 0x00,0x01,0x02,0x00,0x15,0x00,0x15,0x20, + 0x00,0x01,0x02,0x00,0x15,0x00,0x16,0x46, + 0x00,0x01,0x02,0x00,0x15,0x00,0x20,0x20, + 0x00,0x01,0x02,0x00,0x15,0x00,0x10,0x22, + 0x00,0x01,0x02,0x00,0x15,0x00,0x43,0x6c, + 0x00,0x01,0x02,0x00,0x15,0x00,0x6f,0x73, + 0x00,0x01,0x02,0x00,0x15,0x00,0x65,0x64, + 0x00,0x01,0x02,0x00,0x15,0x00,0x20,0x43, + 0x00,0x01,0x02,0x00,0x15,0x00,0x61,0x70, + 0x00,0x01,0x02,0x00,0x15,0x00,0x74,0x69, + 0x00,0x01,0x02,0x00,0x15,0x00,0x6f,0x6e , + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x2f, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x41,0x00, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x45,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x4f,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x75,0x00, + + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x2f, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x41,0x00, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x45,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x4f,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x75,0x00, + + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x2f, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x41,0x00, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x45,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x4f,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x75,0x00, + + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x2f, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x41,0x00, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x45,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x4f,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x75,0x00, + }; + + unsigned char pBuffer11[] ={ 1,21, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x2f, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x41,0x00, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x45,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x4f,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x75,0x00, + + }; + + + int length = N_ELEMENTS (pBuffer); + + + vbi_bool success; + + //if (!init_window (argc, argv)) + // exit (EXIT_FAILURE); + + vbi = vbi_decoder_new (); + + assert (NULL != vbi); + + success = vbi_event_handler_add (vbi, VBI_EVENT_CAPTION, + cc_handler, /* used_data */ NULL); + assert (success); + + + success = vbi_event_handler_add (vbi, VBI_EVENT_ASPECT | VBI_EVENT_PROG_INFO, + xds_handler, /* used_data */ NULL); + assert (success); + + + + + //if (isatty (STDIN_FILENO)) { + // hello_world (); + //} else { + struct stream *st; + + printf("read_stream_new\n"); + st = read_stream_new (pBuffer,length, + FILE_FORMAT_SLICED, + 0, + decode_frame); + + //st = read_stream_new (/* filename: stdin */ NULL, + // FILE_FORMAT_SLICED, + // /* ts_pid */ 0, + // decode_frame); + stream_loop (st); + stream_delete (st); + //} + + printf ("Done.\n"); + + //for (;;) + // xevent (33333); + + vbi_decoder_delete (vbi); + + exit (EXIT_SUCCESS); +} + +#else /* X_DISPLAY_MISSING */ + +int +main (int argc, + char ** argv) +{ + printf ("Could not find X11 or has been disabled " + "at configuration time\n"); + exit(EXIT_FAILURE); +} + +#endif diff --git a/ntsc_decode/caption.h b/ntsc_decode/caption.h new file mode 100755 index 0000000..a60fff8 --- a/dev/null +++ b/ntsc_decode/caption.h @@ -0,0 +1,34 @@ +/*******************************************************************
+ *
+ * Copyright (C) 2010 by Amlogic, Inc. All Rights Reserved.
+ *
+ * Description: decode is define
+ *
+ * Author: kui zhang
+ *
+ *******************************************************************/
+
+
+#ifndef _TRANSFER_VOD_H_
+#define _TRANSFER_VOD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+#include<unistd.h>
+
+
+typedef void (* NTSC_XDS_status_cb)(int what, int arg);
+
+int start_demux_ntsc();
+
+
+void decode_ntsc_xds_set_callback(NTSC_XDS_status_cb cb_ptr);
+
+#endif
+
+
+
+
diff --git a/ntsc_decode/decode.c b/ntsc_decode/decode.c index c9545c6..f5bb719 100755 --- a/ntsc_decode/decode.c +++ b/ntsc_decode/decode.c @@ -105,6 +105,8 @@ static vbi_pfc_demux * pfc; static vbi_idl_demux * idl; static vbi_xds_demux * xds; +NTSC_XDS_status_cb ntsc_xds_callback = NULL; + extern void _vbi_pfc_block_dump (const vbi_pfc_block * pb, FILE * fp, @@ -274,6 +276,8 @@ xds_cb (vbi_xds_demux * xd, printf("************xds_cb**********\n"); vbi_program_info *pi; _vbi_xds_packet_dump (xp, stdout); + + ntsc_xds_callback(NTSC_XDS_CB_STATUS,vbi_xds_subclass_program); return TRUE; /* no errors */ } @@ -990,12 +994,13 @@ static int option_index; int start_demux_ntsc(){ + unsigned char pBuffer [5100] ; memset(pBuffer,0, 5100 ); option_decode_xds = TRUE; option_decode_caption = TRUE; int length = N_ELEMENTS (pBuffer); - + ntsc_xds_callback(NTSC_XDS_CB_STATUS,NTSC_XDS_CB_STATUS_STARTED); xds = vbi_xds_demux_new (xds_cb, /* used_data */ NULL); if (NULL == xds) @@ -1020,3 +1025,7 @@ int start_demux_ntsc(){ } +void decode_ntsc_xds_set_callback(NTSC_XDS_status_cb cb_ptr){ + printf("decode_ntsc_xds_set_callback"); + ntsc_xds_callback = cb_ptr; +} diff --git a/ntsc_decode/decode.h b/ntsc_decode/decode.h new file mode 100755 index 0000000..c2166b3 --- a/dev/null +++ b/ntsc_decode/decode.h @@ -0,0 +1,40 @@ +/*******************************************************************
+ *
+ * Copyright (C) 2010 by Amlogic, Inc. All Rights Reserved.
+ *
+ * Description: decode is define
+ *
+ * Author: kui zhang
+ *
+ *******************************************************************/
+
+
+#ifndef _TRANSFER_VOD_H_
+#define _TRANSFER_VOD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+#include<unistd.h>
+
+#define NTSC_XDS_CB_STATUS 0x1000
+#define NTSC_XDS_CB_STATUS_STARTED 0x1001
+#define NTSC_XDS_CB_STATUS_STOPPED 0x1002
+
+#define NTSC_XDS_CB_ERROR 0x2000
+#define NTSC_XDS_CB_ERROR_MEMORY 0x2002
+#define NTSC_XDS_CB_ERROR_TIMEOUT 0x2003
+#define NTSC_XDS_CB_ERROR_aaa 0x2010
+
+typedef void (* NTSC_XDS_status_cb)(int what, int arg);
+
+int start_demux_ntsc();
+
+
+void decode_ntsc_xds_set_callback(NTSC_XDS_status_cb cb_ptr);
+
+
+
+
diff --git a/ntsc_decode/ntsc_dmx/am_vbi_dmx.c b/ntsc_decode/ntsc_dmx/am_vbi_dmx.c new file mode 100755 index 0000000..cd71608 --- a/dev/null +++ b/ntsc_decode/ntsc_dmx/am_vbi_dmx.c @@ -0,0 +1,708 @@ +/*************************************************************************** + * Copyright C 2009 by Amlogic, Inc. All Rights Reserved. + */ +/**\file + * \brief + * + * \author Gong Ke <ke.gong@amlogic.com> + * \date 2010-05-21: create the document + ***************************************************************************/ + +#define AM_DEBUG_LEVEL 1 + +#include "am_vbi_internal.h" +#include "vbi_dmx.h" +#include <string.h> +#include <assert.h> + +/**************************************************************************** + * Macro definitions + ***************************************************************************/ + +//#define DMX_WAIT_CB /*Wait callback function stop in API*/ + +#define DMX_SYNC + +#define DMX_BUF_SIZE (4096) +#define DMX_POLL_TIMEOUT (200) + +#define DMX_DEV_COUNT (2) + + +#define DMX_CHAN_ISSET_FILTER(chan,fid) ((chan)->filter_mask[(fid)>>3]&(1<<((fid)&3))) +#define DMX_CHAN_SET_FILTER(chan,fid) ((chan)->filter_mask[(fid)>>3]|=(1<<((fid)&3))) +#define DMX_CHAN_CLR_FILTER(chan,fid) ((chan)->filter_mask[(fid)>>3]&=~(1<<((fid)&3))) + + +/**************************************************************************** + * Static data + ***************************************************************************/ + + +extern const AM_VBI_Driver_t linux_vbi_drv ; + +pthread_mutex_t am_gAdpLock = PTHREAD_MUTEX_INITIALIZER; + +static AM_VBI_Device_t dmx_devices[DMX_DEV_COUNT] = +{ + +{ +.drv = &linux_vbi_drv, +.src = DUAL_FD1, +}, +{ +.drv = &linux_vbi_drv, +.src = DUAL_FD2, +} +}; + +/**************************************************************************** + * Static functions + ***************************************************************************/ + +/**\brief 鏍规嵁璁惧鍙峰彇寰楄澶囩粨鏋勬寚閽*/ +static inline AM_ErrorCode_t dmx_get_dev(int dev_no, AM_VBI_Device_t **dev) +{ + if((dev_no<0) || (dev_no>=DMX_DEV_COUNT)) + { + AM_DEBUG("invalid demux device number %d, must in(%d~%d)", dev_no, 0, DMX_DEV_COUNT-1); + return AM_DMX_ERR_INVALID_DEV_NO; + } + + *dev = &dmx_devices[dev_no]; + return AM_SUCCESS; +} + +/**\brief 鏍规嵁璁惧鍙峰彇寰楄澶囩粨鏋勫苟妫鏌ヨ澶囨槸鍚﹀凡缁忔墦寮*/ +static inline AM_ErrorCode_t dmx_get_openned_dev(int dev_no, AM_VBI_Device_t **dev) +{ + int ret = (dmx_get_dev(dev_no, dev)); + + if(!(*dev)->openned) + { + AM_DEBUG( "demux device %d has not been openned", dev_no); + return AM_DMX_ERR_INVALID_DEV_NO; + } + + return AM_SUCCESS; +} + +/**\brief 鏍规嵁ID鍙栧緱瀵瑰簲filter缁撴瀯锛屽苟妫鏌ヨ澶囨槸鍚﹀湪浣跨敤*/ +static inline AM_ErrorCode_t dmx_get_used_filter(AM_VBI_Device_t *dev, int filter_id, AM_VBI_Filter_t **pf) +{ + AM_VBI_Filter_t *filter; + + if((filter_id<0) || (filter_id>=DMX_FILTER_COUNT)) + { + AM_DEBUG( "invalid filter id, must in %d~%d", 0, DMX_FILTER_COUNT-1); + return AM_DMX_ERR_INVALID_ID; + } + + filter = &dev->filters[filter_id]; + + if(!filter->used) + { + AM_DEBUG( "filter %d has not been allocated", filter_id); + return AM_DMX_ERR_NOT_ALLOCATED; + } + + *pf = filter; + return AM_SUCCESS; +} + +/**\brief 鏁版嵁妫娴嬬嚎绋*/ +static void* dmx_data_thread(void *arg) +{ + AM_VBI_Device_t *dev = (AM_VBI_Device_t*)arg; + static uint8_t sec_buf[4096]; + uint8_t *sec; + int sec_len; + AM_VBI_FilterMask_t mask; + AM_ErrorCode_t ret; + int count = 0; + while(dev->enable_thread) + { + //**********************************temp**************** + AM_DEBUG( "***************thread count = %d\n",count); + if(count ++ == 100) + break; + //**********************************finish**************** + AM_DMX_FILTER_MASK_CLEAR(&mask); + int id; + + ret = dev->drv->poll(dev, &mask, DMX_POLL_TIMEOUT); + if(ret==AM_SUCCESS) + { + AM_DEBUG( "***************thread AM_SUCCESS **********\n"); + if(AM_DMX_FILTER_MASK_ISEMPTY(&mask)) + continue; + +#if defined(DMX_WAIT_CB) || defined(DMX_SYNC) + pthread_mutex_lock(&dev->lock); + dev->flags |= DMX_FL_RUN_CB; + pthread_mutex_unlock(&dev->lock); +#endif + + for(id=0; id<DMX_FILTER_COUNT; id++) + { + AM_VBI_Filter_t *filter=&dev->filters[id]; + AM_DMX_DataCb cb; + void *data; + + if(!AM_DMX_FILTER_MASK_ISSET(&mask, id)) + continue; + + if(!filter->enable || !filter->used) + continue; + + sec_len = sizeof(sec_buf); + +#ifndef DMX_WAIT_CB + pthread_mutex_lock(&dev->lock); +#endif + if(!filter->enable || !filter->used) + { + ret = AM_FAILURE; + } + else + { + cb = filter->cb; + data = filter->user_data; + ret = dev->drv->read(dev, filter, sec_buf, &sec_len); + } +#ifndef DMX_WAIT_CB + pthread_mutex_unlock(&dev->lock); +#endif + if(ret==AM_DMX_ERR_TIMEOUT) + { + sec = NULL; + sec_len = 0; + } + else if(ret!=AM_SUCCESS) + { + continue; + } + else + { + sec = sec_buf; + } + + if(cb) + { + if(id && sec) + AM_DEBUG( "filter %d data callback len fd:%d len:%d, %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + id, (int)filter->drv_data, sec_len, + sec[0], sec[1], sec[2], sec[3], sec[4], + sec[5], sec[6], sec[7], sec[8], sec[9]); + cb(dev->dev_no, id, sec, sec_len, data); + if(id && sec) + AM_DEBUG( "filter %d data callback ok", id); + } + } +#if defined(DMX_WAIT_CB) || defined(DMX_SYNC) + pthread_mutex_lock(&dev->lock); + dev->flags &= ~DMX_FL_RUN_CB; + pthread_mutex_unlock(&dev->lock); + pthread_cond_broadcast(&dev->cond); +#endif + } + else + AM_DEBUG( "poll fail \n"); + } + + return NULL; +} + +/**\brief 绛夊緟鍥炶皟鍑芥暟鍋滄杩愯*/ +static inline AM_ErrorCode_t dmx_wait_cb(AM_VBI_Device_t *dev) +{ +#ifdef DMX_WAIT_CB + if(dev->thread!=pthread_self()) + { + while(dev->flags&DMX_FL_RUN_CB) + pthread_cond_wait(&dev->cond, &dev->lock); + } +#endif + return AM_SUCCESS; +} + +/**\brief 鍋滄Section杩囨护鍣*/ +static AM_ErrorCode_t dmx_stop_filter(AM_VBI_Device_t *dev, AM_VBI_Filter_t *filter) +{ + AM_ErrorCode_t ret = AM_SUCCESS; + + if(!filter->used || !filter->enable) + { + return ret; + } + + if(dev->drv->enable_filter) + { + ret = dev->drv->enable_filter(dev, filter, AM_FALSE); + } + + if(ret>=0) + { + filter->enable = AM_FALSE; + } + + return ret; +} + +/**\brief 閲婃斁杩囨护鍣*/ +static int dmx_free_filter(AM_VBI_Device_t *dev, AM_VBI_Filter_t *filter) +{ + AM_ErrorCode_t ret = AM_SUCCESS; + + if(!filter->used) + return ret; + + ret = dmx_stop_filter(dev, filter); + + if(ret==AM_SUCCESS) + { + if(dev->drv->free_filter) + { + ret = dev->drv->free_filter(dev, filter); + } + } + + if(ret==AM_SUCCESS) + { + filter->used=AM_FALSE; + } + + return ret; +} + +/**************************************************************************** + * API functions + ***************************************************************************/ + +/**\brief 鎵撳紑瑙e鐢ㄨ澶 + * \param dev_no 瑙e鐢ㄨ澶囧彿 + * \param[in] para 瑙e鐢ㄨ澶囧紑鍚弬鏁 + * \return + * - AM_SUCCESS 鎴愬姛 + * - 鍏朵粬鍊 閿欒浠g爜(瑙乤m_dmx.h) + */ +AM_ErrorCode_t AM_NTSC_DMX_Open(int dev_no, const AM_DMX_OpenPara_t *para) +{ + AM_VBI_Device_t *dev; + AM_ErrorCode_t ret = AM_SUCCESS; + + assert(para); + + ret = (dmx_get_dev(dev_no, &dev)); + + pthread_mutex_lock(&am_gAdpLock); + + if(dev->openned) + { + AM_DEBUG( "demux device %d has already been openned", dev_no); + ret = AM_DMX_ERR_BUSY; + goto final; + } + + dev->dev_no = dev_no; + + if(dev->drv->open) + { + ret = dev->drv->open(dev, para); + } + + if(ret==AM_SUCCESS) + { + pthread_mutex_init(&dev->lock, NULL); + pthread_cond_init(&dev->cond, NULL); + dev->enable_thread = AM_TRUE; + dev->flags = 0; + + if(pthread_create(&dev->thread, NULL, dmx_data_thread, dev)) + { + pthread_mutex_destroy(&dev->lock); + pthread_cond_destroy(&dev->cond); + ret = AM_DMX_ERR_CANNOT_CREATE_THREAD; + } + } + + if(ret==AM_SUCCESS) + { + dev->openned = AM_TRUE; + } +final: + pthread_mutex_unlock(&am_gAdpLock); + + return ret; +} + +/**\brief 鍏抽棴瑙e鐢ㄨ澶 + * \param dev_no 瑙e鐢ㄨ澶囧彿 + * \return + * - AM_SUCCESS 鎴愬姛 + * - 鍏朵粬鍊 閿欒浠g爜(瑙乤m_dmx.h) + */ +AM_ErrorCode_t AM_NTSC_DMX_Close(int dev_no) +{ + AM_VBI_Device_t *dev; + AM_ErrorCode_t ret = AM_SUCCESS; + int i; + + ret = (dmx_get_openned_dev(dev_no, &dev)); + + pthread_mutex_lock(&am_gAdpLock); + + dev->enable_thread = AM_FALSE; + pthread_join(dev->thread, NULL); + + for(i=0; i<DMX_FILTER_COUNT; i++) + { + dmx_free_filter(dev, &dev->filters[i]); + } + + if(dev->drv->close) + { + dev->drv->close(dev); + } + + pthread_mutex_destroy(&dev->lock); + pthread_cond_destroy(&dev->cond); + + dev->openned = AM_FALSE; + + pthread_mutex_unlock(&am_gAdpLock); + + return ret; +} + +/**\brief 鍒嗛厤涓涓繃婊ゅ櫒 + * \param dev_no 瑙e鐢ㄨ澶囧彿 + * \param[out] fhandle 杩斿洖杩囨护鍣ㄥ彞鏌 + * \return + * - AM_SUCCESS 鎴愬姛 + * - 鍏朵粬鍊 閿欒浠g爜(瑙乤m_dmx.h) + */ +AM_ErrorCode_t AM_NTSC_DMX_AllocateFilter(int dev_no, int *fhandle) +{ + AM_VBI_Device_t *dev; + AM_ErrorCode_t ret = AM_SUCCESS; + int fid; + + assert(fhandle); + + ret = (dmx_get_openned_dev(dev_no, &dev)); + + pthread_mutex_lock(&dev->lock); + + for(fid=0; fid<DMX_FILTER_COUNT; fid++) + { + AM_DEBUG( "dev->filters[fid].used = %d\n",dev->filters[fid].used); + if(!dev->filters[fid].used) + break; + } + + if(fid>=DMX_FILTER_COUNT) + { + AM_DEBUG( "no free section filter"); + ret = AM_DMX_ERR_NO_FREE_FILTER; + } + + if(ret==AM_SUCCESS) + { + AM_DEBUG( "AM_NTSC_DMX_AllocateFilter AM_SUCCESS fid = %d\n",fid); + dmx_wait_cb(dev); + + dev->filters[fid].id = fid; + if(dev->drv->alloc_filter) + { + ret = dev->drv->alloc_filter(dev, &dev->filters[fid]); + } + } + + if(ret==AM_SUCCESS) + { + dev->filters[fid].used = AM_TRUE; + *fhandle = fid; + + AM_DEBUG( "allocate filter %d \n", fid); + } + + pthread_mutex_unlock(&dev->lock); + + return ret; +} + + +/**\brief 閲婃斁涓涓繃婊ゅ櫒 + * \param dev_no 瑙e鐢ㄨ澶囧彿 + * \param fhandle 杩囨护鍣ㄥ彞鏌 + * \return + * - AM_SUCCESS 鎴愬姛 + * - 鍏朵粬鍊 閿欒浠g爜(瑙乤m_dmx.h) + */ +AM_ErrorCode_t AM_NTSC_DMX_FreeFilter(int dev_no, int fhandle) +{ + AM_VBI_Device_t *dev; + AM_VBI_Filter_t *filter; + AM_ErrorCode_t ret = AM_SUCCESS; + + ret = (dmx_get_openned_dev(dev_no, &dev)); + + pthread_mutex_lock(&dev->lock); + + ret = dmx_get_used_filter(dev, fhandle, &filter); + + if(ret==AM_SUCCESS) + { + dmx_wait_cb(dev); + ret = dmx_free_filter(dev, filter); + AM_DEBUG( "free filter %d", fhandle); + } + + pthread_mutex_unlock(&dev->lock); + + return ret; +} + +/**\brief 璁╀竴涓繃婊ゅ櫒寮濮嬭繍琛 + * \param dev_no 瑙e鐢ㄨ澶囧彿 + * \param fhandle 杩囨护鍣ㄥ彞鏌 + * \return + * - AM_SUCCESS 鎴愬姛 + * - 鍏朵粬鍊 閿欒浠g爜(瑙乤m_dmx.h) + */ +AM_ErrorCode_t AM_NTSC_DMX_StartFilter(int dev_no, int fhandle) +{ + AM_DEBUG("AM_NTSC_DMX_StartFilter*************\n"); + AM_VBI_Device_t *dev; + AM_VBI_Filter_t *filter = NULL; + AM_ErrorCode_t ret = AM_SUCCESS; + + ret = (dmx_get_openned_dev(dev_no, &dev)); + + pthread_mutex_lock(&dev->lock); + + ret = dmx_get_used_filter(dev, fhandle, &filter); + + if(!filter->enable) + { + if(ret==AM_SUCCESS) + { + if(dev->drv->enable_filter) + { + ret = dev->drv->enable_filter(dev, filter, AM_TRUE); + } + } + + if(ret==AM_SUCCESS) + { + filter->enable = AM_TRUE; + } + } + + pthread_mutex_unlock(&dev->lock); + + return ret; +} + +/**\brief 鍋滄涓涓繃婊ゅ櫒 + * \param dev_no 瑙e鐢ㄨ澶囧彿 + * \param fhandle 杩囨护鍣ㄥ彞鏌 + * \return + * - AM_SUCCESS 鎴愬姛 + * - 鍏朵粬鍊 閿欒浠g爜(瑙乤m_dmx.h) + */ +AM_ErrorCode_t AM_NTSC_DMX_StopFilter(int dev_no, int fhandle) +{ + AM_VBI_Device_t *dev; + AM_VBI_Filter_t *filter = NULL; + AM_ErrorCode_t ret = AM_SUCCESS; + + ret = (dmx_get_openned_dev(dev_no, &dev)); + + pthread_mutex_lock(&dev->lock); + + ret = dmx_get_used_filter(dev, fhandle, &filter); + + if(filter->enable) + { + if(ret==AM_SUCCESS) + { + dmx_wait_cb(dev); + ret = dmx_stop_filter(dev, filter); + } + } + + pthread_mutex_unlock(&dev->lock); + + return ret; +} + +/**\brief 璁剧疆涓涓繃婊ゅ櫒鐨勭紦鍐插尯澶у皬 + * \param dev_no 瑙e鐢ㄨ澶囧彿 + * \param fhandle 杩囨护鍣ㄥ彞鏌 + * \param size 缂撳啿鍖哄ぇ灏 + * \return + * - AM_SUCCESS 鎴愬姛 + * - 鍏朵粬鍊 閿欒浠g爜(瑙乤m_dmx.h) + */ +AM_ErrorCode_t AM_NTSC_DMX_SetBufferSize(int dev_no, int fhandle, int size) +{ + AM_VBI_Device_t *dev; + AM_VBI_Filter_t *filter; + AM_ErrorCode_t ret = AM_SUCCESS; + + ret = (dmx_get_openned_dev(dev_no, &dev)); + + pthread_mutex_lock(&dev->lock); + + if(!dev->drv->set_buf_size) + { + AM_DEBUG( "do not support set_buf_size"); + ret = AM_DMX_ERR_NOT_SUPPORTED; + } + + if(ret==AM_SUCCESS) + ret = dmx_get_used_filter(dev, fhandle, &filter); + + if(ret==AM_SUCCESS) + ret = dev->drv->set_buf_size(dev, filter, size); + + pthread_mutex_unlock(&dev->lock); + + return ret; +} + +/**\brief 鍙栧緱涓涓繃婊ゅ櫒瀵瑰簲鐨勫洖璋冨嚱鏁板拰鐢ㄦ埛鍙傛暟 + * \param dev_no 瑙e鐢ㄨ澶囧彿 + * \param fhandle 杩囨护鍣ㄥ彞鏌 + * \param[out] cb 杩斿洖杩囨护鍣ㄥ搴旂殑鍥炶皟鍑芥暟 + * \param[out] data 杩斿洖鐢ㄦ埛鍙傛暟 + * \return + * - AM_SUCCESS 鎴愬姛 + * - 鍏朵粬鍊 閿欒浠g爜(瑙乤m_dmx.h) + */ +AM_ErrorCode_t AM_NTSC_DMX_GetCallback(int dev_no, int fhandle, AM_DMX_DataCb *cb, void **data) +{ + AM_VBI_Device_t *dev; + AM_VBI_Filter_t *filter; + AM_ErrorCode_t ret = AM_SUCCESS; + + ret = (dmx_get_openned_dev(dev_no, &dev)); + + pthread_mutex_lock(&dev->lock); + + ret = dmx_get_used_filter(dev, fhandle, &filter); + + if(ret==AM_SUCCESS) + { + if(cb) + *cb = filter->cb; + + if(data) + *data = filter->user_data; + } + + pthread_mutex_unlock(&dev->lock); + + return ret; +} + +/**\brief 璁剧疆涓涓繃婊ゅ櫒瀵瑰簲鐨勫洖璋冨嚱鏁板拰鐢ㄦ埛鍙傛暟 + * \param dev_no 瑙e鐢ㄨ澶囧彿 + * \param fhandle 杩囨护鍣ㄥ彞鏌 + * \param[in] cb 鍥炶皟鍑芥暟 + * \param[in] data 鍥炶皟鍑芥暟鐨勭敤鎴峰弬鏁 + * \return + * - AM_SUCCESS 鎴愬姛 + * - 鍏朵粬鍊 閿欒浠g爜(瑙乤m_dmx.h) + */ +AM_ErrorCode_t AM_NTSC_DMX_SetCallback(int dev_no, int fhandle, AM_DMX_DataCb cb, void *data) +{ + AM_DEBUG("AM_NTSC_DMX_SetCallback fhandle = %d\n",fhandle); + AM_VBI_Device_t *dev; + AM_VBI_Filter_t *filter; + AM_ErrorCode_t ret = AM_SUCCESS; + + ret = (dmx_get_openned_dev(dev_no, &dev)); + + pthread_mutex_lock(&dev->lock); + + ret = dmx_get_used_filter(dev, fhandle, &filter); + + if(ret==AM_SUCCESS) + { + AM_DEBUG("AM_NTSC_DMX_SetCallback AM_SUCCESS\n"); + dmx_wait_cb(dev); + + filter->cb = cb; + filter->user_data = data; + } + + pthread_mutex_unlock(&dev->lock); + + return ret; +} + +/**\brief 璁剧疆瑙e鐢ㄨ澶囩殑杈撳叆婧 + * \param dev_no 瑙e鐢ㄨ澶囧彿 + * \param src 杈撳叆婧 + * \return + * - AM_SUCCESS 鎴愬姛 + * - 鍏朵粬鍊 閿欒浠g爜(瑙乤m_dmx.h) + */ +AM_ErrorCode_t AM_NTSC_DMX_SetSource(int dev_no, AM_VBI_DMX_Source_t src) +{ + AM_VBI_Device_t *dev; + AM_ErrorCode_t ret = AM_SUCCESS; + + ret = (dmx_get_openned_dev(dev_no, &dev)); + + pthread_mutex_lock(&dev->lock); + if(!dev->drv->set_source) + { + AM_DEBUG( "do not support set_source"); + ret = AM_DMX_ERR_NOT_SUPPORTED; + } + + if(ret==AM_SUCCESS) + { + ret = dev->drv->set_source(dev, src); + } + + pthread_mutex_unlock(&dev->lock); + + if(ret==AM_SUCCESS) + { + pthread_mutex_lock(&am_gAdpLock); + dev->src = src; + pthread_mutex_unlock(&am_gAdpLock); + } + + return ret; +} + +/**\brief DMX鍚屾锛屽彲鐢ㄤ簬绛夊緟鍥炶皟鍑芥暟鎵ц瀹屾瘯 + * \param dev_no 瑙e鐢ㄨ澶囧彿 + * \return + * - AM_SUCCESS 鎴愬姛 + * - 鍏朵粬鍊 閿欒浠g爜(瑙乤m_dmx.h) + */ +AM_ErrorCode_t AM_NTSC_DMX_Sync(int dev_no) +{ + AM_VBI_Device_t *dev; + AM_ErrorCode_t ret = AM_SUCCESS; + + ret = (dmx_get_openned_dev(dev_no, &dev)); + + pthread_mutex_lock(&dev->lock); + if(dev->thread!=pthread_self()) + { + while(dev->flags&DMX_FL_RUN_CB) + pthread_cond_wait(&dev->cond, &dev->lock); + } + pthread_mutex_unlock(&dev->lock); + + return ret; +} + diff --git a/ntsc_decode/ntsc_dmx/am_vbi_internal.h b/ntsc_decode/ntsc_dmx/am_vbi_internal.h new file mode 100755 index 0000000..9656373 --- a/dev/null +++ b/ntsc_decode/ntsc_dmx/am_vbi_internal.h @@ -0,0 +1,111 @@ +/*************************************************************************** + * Copyright C 2009 by Amlogic, Inc. All Rights Reserved. + */ +/**\file + * \brief 瑙e鐢ㄨ澶 + * + * \author Gong Ke <ke.gong@amlogic.com> + * \date 2010-05-21: create the document + ***************************************************************************/ + +#ifndef _AM_VBI_INTERNAL_H +#define _AM_VBI_INTERNAL_H + +#include <vbi_dmx.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <locale.h> +#include <assert.h> +#include <unistd.h> +#include <errno.h> +#include <time.h> +#include <pthread.h> + #ifdef __cplusplus + extern "C" + { + #endif + + +/**************************************************************************** + * Macro definitions + ***************************************************************************/ + +#define DMX_FILTER_COUNT (1) + +#define DMX_DRIVER_LENGTH (32) + +#define DMX_FL_RUN_CB (1) + +/**************************************************************************** + * Type definitions + ***************************************************************************/ + +/**\brief 瑙e鐢ㄨ澶*/ +typedef struct AM_VBI_Device AM_VBI_Device_t; + +/**\brief 杩囨护鍣*/ +typedef struct AM_VBI_Filter AM_VBI_Filter_t; + +/**\brief 杩囨护鍣ㄤ綅灞忚斀*/ +typedef uint32_t AM_VBI_FilterMask_t; + +#define AM_DMX_FILTER_MASK_ISEMPTY(m) (!(*(m))) +#define AM_DMX_FILTER_MASK_CLEAR(m) (*(m)=0) +#define AM_DMX_FILTER_MASK_ISSET(m,i) (*(m)&(1<<(i))) +#define AM_DMX_FILTER_MASK_SET(m,i) (*(m)|=(1<<(i))) + +/**\brief 瑙e鐢ㄨ澶囬┍鍔*/ +typedef struct +{ + AM_ErrorCode_t (*open)(AM_VBI_Device_t *dev, const AM_DMX_OpenPara_t *para); + AM_ErrorCode_t (*close)(AM_VBI_Device_t *dev); + AM_ErrorCode_t (*alloc_filter)(AM_VBI_Device_t *dev, AM_VBI_Filter_t *filter); + AM_ErrorCode_t (*free_filter)(AM_VBI_Device_t *dev, AM_VBI_Filter_t *filter); + AM_ErrorCode_t (*enable_filter)(AM_VBI_Device_t *dev, AM_VBI_Filter_t *filter, vbi_bool enable); + AM_ErrorCode_t (*set_buf_size)(AM_VBI_Device_t *dev, AM_VBI_Filter_t *filter, int size); + AM_ErrorCode_t (*poll)(AM_VBI_Device_t *dev, AM_VBI_FilterMask_t *mask, int timeout); + AM_ErrorCode_t (*read)(AM_VBI_Device_t *dev, AM_VBI_Filter_t *filter, uint8_t *buf, int *size); + AM_ErrorCode_t (*set_source)(AM_VBI_Device_t *dev, AM_VBI_DMX_Source_t src); +} AM_VBI_Driver_t; + +/**\brief Section杩囨护鍣*/ +struct AM_VBI_Filter +{ + void *drv_data; /**< 椹卞姩绉佹湁鏁版嵁*/ + vbi_bool used; /**< 姝ilter鏄惁宸茬粡鍒嗛厤*/ + vbi_bool enable; /**< 姝ilter璁惧鏄惁浣胯兘*/ + int id; /**< Filter ID*/ + AM_DMX_DataCb cb; /**< 瑙e鐢ㄦ暟鎹洖璋冨嚱鏁*/ + void *user_data; /**< 鏁版嵁鍥炶皟鍑芥暟鐢ㄦ埛鍙傛暟*/ +}; + +/**\brief 瑙e鐢ㄨ澶*/ +struct AM_VBI_Device +{ + int dev_no; /**< 璁惧鍙*/ + const AM_VBI_Driver_t *drv; /**< 璁惧椹卞姩*/ + void *drv_data;/**< 椹卞姩绉佹湁鏁版嵁*/ + AM_VBI_Filter_t filters[DMX_FILTER_COUNT]; /**< 璁惧涓殑Filter*/ + vbi_bool openned; /**< 璁惧宸茬粡鎵撳紑*/ + vbi_bool enable_thread; /**< 鏁版嵁绾跨▼宸茬粡杩愯*/ + int flags; /**< 绾跨▼杩愯鐘舵佹帶鍒舵爣蹇*/ + pthread_t thread; /**< 鏁版嵁妫娴嬬嚎绋*/ + pthread_mutex_t lock; /**< 璁惧淇濇姢浜掓枼浣*/ + pthread_cond_t cond; /**< 鏉′欢鍙橀噺*/ + AM_VBI_DMX_Source_t src; /**< TS杈撳叆婧*/ +}; + + +/**************************************************************************** + * Function prototypes + ***************************************************************************/ + + + #ifdef __cplusplus + } + #endif + +#endif + diff --git a/ntsc_decode/ntsc_dmx/include/vbi_dmx.h b/ntsc_decode/ntsc_dmx/include/vbi_dmx.h new file mode 100755 index 0000000..ff04cd1 --- a/dev/null +++ b/ntsc_decode/ntsc_dmx/include/vbi_dmx.h @@ -0,0 +1,253 @@ +/*************************************************************************** + * Copyright C 2009 by Amlogic, Inc. All Rights Reserved. + */ +/**\file + * \brief 瑙e鐢ㄨ澶囨ā鍧 + * + * \author Gong Ke <ke.gong@amlogic.com> + * \date 2010-05-21: create the document + ***************************************************************************/ + +#ifndef _VBI_DMX_H +#define _VBI_DMX_H + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <locale.h> +#include <assert.h> +#include <unistd.h> +#include <errno.h> +#include <time.h> +#include <pthread.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <errno.h> +#include <dlfcn.h> +#include <sys/mman.h> +#include <sched.h> +#include <signal.h> + + +#ifdef __cplusplus +extern "C" +{ +#endif + +/**************************************************************************** + * Macro definitions + ***************************************************************************/ + +/**************************************************************************** + * Error code definitions + ****************************************************************************/ + +/**\brief 瑙e鐢ㄦā鍧楅敊璇唬鐮*/ +enum AM_VBI_ErrorCode +{ + AM_DMX_ERROR_BASE, + AM_DMX_ERR_INVALID_DEV_NO, /**< 璁惧鍙锋棤鏁*/ + AM_DMX_ERR_INVALID_ID, /**< 杩囨护鍣↖D鏃犳晥*/ + AM_DMX_ERR_BUSY, /**< 璁惧宸茬粡琚墦寮*/ + AM_DMX_ERR_NOT_ALLOCATED, /**< 璁惧娌℃湁鍒嗛厤*/ + AM_DMX_ERR_CANNOT_CREATE_THREAD, /**< 鏃犳硶鍒涘缓绾跨▼*/ + AM_DMX_ERR_CANNOT_OPEN_DEV, /**< 鏃犳硶鎵撳紑璁惧*/ + AM_DMX_ERR_NOT_SUPPORTED, /**< 涓嶆敮鎸佺殑鎿嶄綔*/ + AM_DMX_ERR_NO_FREE_FILTER, /**< 娌℃湁绌洪棽鐨剆ection杩囨护鍣*/ + AM_DMX_ERR_NO_MEM, /**< 绌洪棽鍐呭瓨涓嶈冻*/ + AM_DMX_ERR_TIMEOUT, /**< 绛夊緟璁惧鏁版嵁瓒呮椂*/ + AM_DMX_ERR_SYS, /**< 绯荤粺鎿嶄綔閿欒*/ + AM_DMX_ERR_NO_DATA, /**< 娌℃湁鏀跺埌鏁版嵁*/ + AM_DMX_ERR_END +}; + +#define VBI_IOC_MAGIC 'X' +#define VBI_IOC_CC_EN _IO (VBI_IOC_MAGIC, 0x01) +#define VBI_IOC_CC_DISABLE _IO (VBI_IOC_MAGIC, 0x02) +#define VBI_IOC_SET_FILTER _IOW(VBI_IOC_MAGIC, 0x03, int) +#define VBI_IOC_S_BUF_SIZE _IOW(VBI_IOC_MAGIC, 0x04, int) +#define VBI_IOC_START _IO (VBI_IOC_MAGIC, 0x05) +#define VBI_IOC_STOP _IO (VBI_IOC_MAGIC, 0x06) +#define DECODER_VBI_VBI_SIZE 0x1000 + +#define VBI_DEV_NO 0 + +#ifndef AM_SUCCESS +#define AM_SUCCESS (0) +#endif + +#ifndef AM_FAILURE +#define AM_FAILURE (-1) +#endif + +#ifndef AM_TRUE +#define AM_TRUE (1) +#endif + +#ifndef AM_FALSE +#define AM_FALSE (0) +#endif + +#define AM_DEBUG printf + +typedef int vbi_bool; + +typedef int AM_ErrorCode_t; + + +/**************************************************************************** + * Type definitions + ***************************************************************************/ + +/**\brief 瑙e鐢ㄨ澶囪緭鍏ユ簮*/ +typedef enum +{ + DUAL_FD1, /**< vbi 杈撳叆0*/ + DUAL_FD2, /**< vbi 杈撳叆1*/ +} AM_VBI_DMX_Source_t; + +/**\brief 瑙e鐢ㄨ澶囧紑鍚弬鏁*/ +typedef struct +{ + int foo; +} AM_DMX_OpenPara_t; + +/**\brief 鏁版嵁鍥炶皟鍑芥暟 + * data涓烘暟鎹紦鍐插尯鎸囬拡锛宭en涓烘暟鎹暱搴︺傚鏋渄ata==NULL琛ㄧずdemux鎺ユ敹鏁版嵁瓒呮椂銆 + */ +typedef void (*AM_DMX_DataCb) (int dev_no, int fhandle, const uint8_t *data, int len, void *user_data); + +/**************************************************************************** + * Function prototypes + ***************************************************************************/ + +/**\brief 鎵撳紑瑙e鐢ㄨ澶 + * \param dev_no 瑙e鐢ㄨ澶囧彿 + * \param[in] para 瑙e鐢ㄨ澶囧紑鍚弬鏁 + * \return + * - AM_SUCCESS 鎴愬姛 + * - 鍏朵粬鍊 閿欒浠g爜(瑙乤m_dmx.h) + */ +extern AM_ErrorCode_t AM_DMX_Open(int dev_no, const AM_DMX_OpenPara_t *para); + +/**\brief 鍏抽棴瑙e鐢ㄨ澶 + * \param dev_no 瑙e鐢ㄨ澶囧彿 + * \return + * - AM_SUCCESS 鎴愬姛 + * - 鍏朵粬鍊 閿欒浠g爜(瑙乤m_dmx.h) + */ +extern AM_ErrorCode_t AM_DMX_Close(int dev_no); + +/**\brief 鍒嗛厤涓涓繃婊ゅ櫒 + * \param dev_no 瑙e鐢ㄨ澶囧彿 + * \param[out] fhandle 杩斿洖杩囨护鍣ㄥ彞鏌 + * \return + * - AM_SUCCESS 鎴愬姛 + * - 鍏朵粬鍊 閿欒浠g爜(瑙乤m_dmx.h) + */ +//extern AM_ErrorCode_t AM_DMX_AllocateFilter(int dev_no, int *fhandle); + +/**\brief 璁惧畾Section杩囨护鍣 + * \param dev_no 瑙e鐢ㄨ澶囧彿 + * \param fhandle 杩囨护鍣ㄥ彞鏌 + * \param[in] params Section杩囨护鍣ㄥ弬鏁 + * \return + * - AM_SUCCESS 鎴愬姛 + * - 鍏朵粬鍊 閿欒浠g爜(瑙乤m_dmx.h) + */ +//extern AM_ErrorCode_t AM_DMX_SetSecFilter(int dev_no, int fhandle, const struct dmx_sct_filter_params *params); + +/**\brief 璁惧畾PES杩囨护鍣 + * \param dev_no 瑙e鐢ㄨ澶囧彿 + * \param fhandle 杩囨护鍣ㄥ彞鏌 + * \param[in] params PES杩囨护鍣ㄥ弬鏁 + * \return + * - AM_SUCCESS 鎴愬姛 + * - 鍏朵粬鍊 閿欒浠g爜(瑙乤m_dmx.h) + */ +//extern AM_ErrorCode_t AM_DMX_SetPesFilter(int dev_no, int fhandle, const struct dmx_pes_filter_params *params); + +/**\brief 閲婃斁涓涓繃婊ゅ櫒 + * \param dev_no 瑙e鐢ㄨ澶囧彿 + * \param fhandle 杩囨护鍣ㄥ彞鏌 + * - AM_SUCCESS 鎴愬姛 + * - 鍏朵粬鍊 閿欒浠g爜(瑙乤m_dmx.h) + */ +//extern AM_ErrorCode_t AM_DMX_FreeFilter(int dev_no, int fhandle); + +/**\brief 璁╀竴涓繃婊ゅ櫒寮濮嬭繍琛 + * \param dev_no 瑙e鐢ㄨ澶囧彿 + * \param fhandle 杩囨护鍣ㄥ彞鏌 + * \return + * - AM_SUCCESS 鎴愬姛 + * - 鍏朵粬鍊 閿欒浠g爜(瑙乤m_dmx.h) + */ +//extern AM_ErrorCode_t AM_DMX_StartFilter(int dev_no, int fhandle); + +/**\brief 鍋滄涓涓繃婊ゅ櫒 + * \param dev_no 瑙e鐢ㄨ澶囧彿 + * \param fhandle 杩囨护鍣ㄥ彞鏌 + * \return + * - AM_SUCCESS 鎴愬姛 + * - 鍏朵粬鍊 閿欒浠g爜(瑙乤m_dmx.h) + */ +//extern AM_ErrorCode_t AM_DMX_StopFilter(int dev_no, int fhandle); + +/**\brief 璁剧疆涓涓繃婊ゅ櫒鐨勭紦鍐插尯澶у皬 + * \param dev_no 瑙e鐢ㄨ澶囧彿 + * \param fhandle 杩囨护鍣ㄥ彞鏌 + * \param size 缂撳啿鍖哄ぇ灏 + * \return + * - AM_SUCCESS 鎴愬姛 + * - 鍏朵粬鍊 閿欒浠g爜(瑙乤m_dmx.h) + */ +extern AM_ErrorCode_t AM_DMX_SetBufferSize(int dev_no, int fhandle, int size); + +/**\brief 鍙栧緱涓涓繃婊ゅ櫒瀵瑰簲鐨勫洖璋冨嚱鏁板拰鐢ㄦ埛鍙傛暟 + * \param dev_no 瑙e鐢ㄨ澶囧彿 + * \param fhandle 杩囨护鍣ㄥ彞鏌 + * \param[out] cb 杩斿洖杩囨护鍣ㄥ搴旂殑鍥炶皟鍑芥暟 + * \param[out] data 杩斿洖鐢ㄦ埛鍙傛暟 + * \return + * - AM_SUCCESS 鎴愬姛 + * - 鍏朵粬鍊 閿欒浠g爜(瑙乤m_dmx.h) + */ +//extern AM_ErrorCode_t AM_DMX_GetCallback(int dev_no, int fhandle, AM_DMX_DataCb *cb, void **data); + +/**\brief 璁剧疆涓涓繃婊ゅ櫒瀵瑰簲鐨勫洖璋冨嚱鏁板拰鐢ㄦ埛鍙傛暟 + * \param dev_no 瑙e鐢ㄨ澶囧彿 + * \param fhandle 杩囨护鍣ㄥ彞鏌 + * \param[in] cb 鍥炶皟鍑芥暟 + * \param[in] data 鍥炶皟鍑芥暟鐨勭敤鎴峰弬鏁 + * \return + * - AM_SUCCESS 鎴愬姛 + * - 鍏朵粬鍊 閿欒浠g爜(瑙乤m_dmx.h) + */ +//extern AM_ErrorCode_t AM_DMX_SetCallback(int dev_no, int fhandle, AM_DMX_DataCb cb, void *data); + +/**\brief 璁剧疆瑙e鐢ㄨ澶囩殑杈撳叆婧 + * \param dev_no 瑙e鐢ㄨ澶囧彿 + * \param src 杈撳叆婧 + * \return + * - AM_SUCCESS 鎴愬姛 + * - 鍏朵粬鍊 閿欒浠g爜(瑙乤m_dmx.h) + */ +//extern AM_ErrorCode_t AM_DMX_SetSource(int dev_no, AM_DMX_Source_t src); + +/**\brief DMX鍚屾锛屽彲鐢ㄤ簬绛夊緟鍥炶皟鍑芥暟鎵ц瀹屾瘯 + * \param dev_no 瑙e鐢ㄨ澶囧彿 + * \return + * - AM_SUCCESS 鎴愬姛 + * - 鍏朵粬鍊 閿欒浠g爜(瑙乤m_dmx.h) + */ +//extern AM_ErrorCode_t AM_DMX_Sync(int dev_no); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/ntsc_decode/ntsc_dmx/linux_vbi/linux_ntsc.c b/ntsc_decode/ntsc_dmx/linux_vbi/linux_ntsc.c new file mode 100755 index 0000000..b132ad8 --- a/dev/null +++ b/ntsc_decode/ntsc_dmx/linux_vbi/linux_ntsc.c @@ -0,0 +1,309 @@ +/*************************************************************************** + * Copyright C 2009 by Amlogic, Inc. All Rights Reserved. + */ +/**\file + * \brief Linux DVB demux 椹卞姩 + * + * \author Gong Ke <ke.gong@amlogic.com> + * \date 2010-07-21: create the document + ***************************************************************************/ + +#define AM_DEBUG_LEVEL 5 + +#include "am_vbi_internal.h" +#include "vbi_dmx.h" +#include <string.h> +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <poll.h> + + +/**************************************************************************** + * Type definitions + ***************************************************************************/ + +typedef struct +{ + char dev_name[DMX_DRIVER_LENGTH]; + int fd[DMX_FILTER_COUNT]; +} VbiDmx_t; + +#define N_ELEMENTS(array) (sizeof (array) / sizeof ((array)[0])) +/**************************************************************************** + * Static data definitions + ***************************************************************************/ + +static AM_ErrorCode_t vbi_open(AM_VBI_Device_t *dev, const AM_DMX_OpenPara_t *para); +static AM_ErrorCode_t vbi_close(AM_VBI_Device_t *dev); +static AM_ErrorCode_t vbi_alloc_filter(AM_VBI_Device_t *dev, AM_VBI_Filter_t *filter); +static AM_ErrorCode_t vbi_free_filter(AM_VBI_Device_t *dev, AM_VBI_Filter_t *filter); +static AM_ErrorCode_t vbi_enable_filter(AM_VBI_Device_t *dev, AM_VBI_Filter_t *filter, vbi_bool enable); +static AM_ErrorCode_t vbi_set_buf_size(AM_VBI_Device_t *dev, AM_VBI_Filter_t *filter, int size); +static AM_ErrorCode_t vbi_poll(AM_VBI_Device_t *dev, AM_VBI_FilterMask_t *mask, int timeout); +static AM_ErrorCode_t vbi_read(AM_VBI_Device_t *dev, AM_VBI_Filter_t *filter, uint8_t *buf, int *size); +static AM_ErrorCode_t vbi_set_source(AM_VBI_Device_t *dev, AM_VBI_DMX_Source_t src); + + + + + +const AM_VBI_Driver_t linux_vbi_drv = { +.open = vbi_open, +.close = vbi_close, +.alloc_filter = vbi_alloc_filter, +.free_filter = vbi_free_filter, +.enable_filter = vbi_enable_filter, +.set_buf_size = vbi_set_buf_size, +.poll = vbi_poll, +.read = vbi_read, +.set_source = vbi_set_source +}; + + +/**************************************************************************** + * Static functions + ***************************************************************************/ + +static AM_ErrorCode_t vbi_open(AM_VBI_Device_t *dev, const AM_DMX_OpenPara_t *para) +{ + VbiDmx_t *dmx; + int i; + AM_DEBUG("vbi_open\n"); + dmx = (VbiDmx_t*)malloc(sizeof(VbiDmx_t)); + if(!dmx) + { + AM_DEBUG( "not enough memory"); + return AM_DMX_ERR_NO_MEM; + } + + //snprintf(dmx->dev_name, sizeof(dmx->dev_name), "/dev/vbi", dev->dev_no); + snprintf(dmx->dev_name, sizeof(dmx->dev_name), "/dev/vbi"); + AM_DEBUG("************dmx->dev_name= %s\n",dmx->dev_name); + for(i=0; i<DMX_FILTER_COUNT; i++) + dmx->fd[i] = -1; + + dev->drv_data = dmx; + return AM_SUCCESS; +} + +static AM_ErrorCode_t vbi_close(AM_VBI_Device_t *dev) +{ + VbiDmx_t *dmx = (VbiDmx_t*)dev->drv_data; + + free(dmx); + return AM_SUCCESS; +} +static unsigned int buf_size1 = 1024; +static AM_ErrorCode_t vbi_alloc_filter(AM_VBI_Device_t *dev, AM_VBI_Filter_t *filter) +{ + AM_DEBUG("************************-----vbi_alloc_filter*********************\n"); + VbiDmx_t *dmx = (VbiDmx_t*)dev->drv_data; + int fd; + + fd = open(dmx->dev_name, O_RDWR|O_NONBLOCK); + if(fd==-1) + { + AM_DEBUG("cannot open \"%s\" (%s)", dmx->dev_name, strerror(errno)); + return AM_DMX_ERR_CANNOT_OPEN_DEV; + }else + AM_DEBUG("can open fd=%d\n",fd); + + dmx->fd[filter->id] = fd; + + + +//*************************************************** + +/* + + int ret = ioctl(fd, VBI_IOC_S_BUF_SIZE, 20000); + if (ret < 0) { + AM_DEBUG("set afe_fd1 ioctl VBI_IOC_S_BUF_SIZE Error!!! \n"); + return 0; + } + //AM_DEBUG("set afe_fd1 ioctl VBI_IOC_S_BUF_SIZE \n"); + int cc_type = 1; + ret = ioctl(fd, VBI_IOC_SET_FILTER, &cc_type);//0,1 + if (ret < 0) { + AM_DEBUG("set afe_fd1 ioctl VBI_IOC_SET_FILTER Error!!! \n"); + return 0; + } + //AM_DEBUG("set afe_fd1 ioctl VBI_IOC_SET_FILTER \n"); + + ret = ioctl(fd, VBI_IOC_START); + if (ret < 0) { + AM_DEBUG("set afe_fd1 ioctl VBI_IOC_START Error!!! \n"); + return 0; + } + +*/ +//*************************************************** + filter->drv_data = (void*)fd; + + return AM_SUCCESS; +} + +static AM_ErrorCode_t vbi_free_filter(AM_VBI_Device_t *dev, AM_VBI_Filter_t *filter) +{ + VbiDmx_t *dmx = (VbiDmx_t*)dev->drv_data; + int fd = (int)filter->drv_data; + + close(fd); + dmx->fd[filter->id] = -1; + + return AM_SUCCESS; +} + + + +static AM_ErrorCode_t vbi_enable_filter(AM_VBI_Device_t *dev, AM_VBI_Filter_t *filter, vbi_bool enable) +{ + AM_DEBUG("**************************vbi_enable_filter*******************\n"); + int fd = (int)filter->drv_data; + int ret; + AM_DEBUG("***********vbi_enable_filter***************enable = %d \n",enable); + if(enable) + ret = ioctl(fd, VBI_IOC_START, 1); + else + ret = ioctl(fd, VBI_IOC_STOP, 1); + + if(ret==-1) + { + AM_DEBUG( "start filter failed (%s)", strerror(errno)); + return AM_DMX_ERR_SYS; + } + + return AM_SUCCESS; +} + +static AM_ErrorCode_t vbi_set_buf_size(AM_VBI_Device_t *dev, AM_VBI_Filter_t *filter, int size) +{ + int fd = (int)filter->drv_data; + int ret; + AM_DEBUG("vbi_set_buf_size fd =%d\n",fd); + + + + + //ret = ioctl(fd, VBI_IOC_S_BUF_SIZE, size); + //if(ret==-1) + //{ + // AM_DEBUG( "set buffer size failed (%s)", strerror(errno)); + // return AM_DMX_ERR_SYS; + //} + //**************************temp****************************/// + + ret = ioctl(fd, VBI_IOC_S_BUF_SIZE, 20000); + if(ret==-1) + { + AM_DEBUG( "set buffer size failed (%s)", strerror(errno)); + return AM_DMX_ERR_SYS; + } + + int cc_type = 1; + ret = ioctl(fd, VBI_IOC_SET_FILTER, &cc_type);//0,1 + if(ret==-1) + { + AM_DEBUG( "set buffer size failed (%s)", strerror(errno)); + return AM_DMX_ERR_SYS; + } + + //**************************finish****************************/// + return AM_SUCCESS; +} + +static AM_ErrorCode_t vbi_poll(AM_VBI_Device_t *dev, AM_VBI_FilterMask_t *mask, int timeout) +{ + AM_DEBUG("vbi_poll \n"); + VbiDmx_t *dmx = (VbiDmx_t*)dev->drv_data; + struct pollfd fds[DMX_FILTER_COUNT]; + int fids[DMX_FILTER_COUNT]; + int i, cnt = 0, ret; + AM_DEBUG("***********************************************\n"); + AM_DEBUG("vbi_poll ***********N_ELEMENTS(dmx->fd) =%d \n",N_ELEMENTS(dmx->fd)); + for(i=0; i<DMX_FILTER_COUNT; i++) + { + if(dmx->fd[i]!=-1) + { + fds[cnt].events = POLLIN|POLLERR; + fds[cnt].fd = dmx->fd[i]; + fids[cnt] = i; + cnt++; + } + } + + if(!cnt) + return AM_DMX_ERR_TIMEOUT; + + AM_DEBUG("vbi_poll *********poll cnt = %d fds[0].fd =%d \n",cnt,fds[0].fd); + ret = poll(fds, cnt, timeout); + if(ret<=0) + { + AM_DEBUG("vbi_poll *********AM_DMX_ERR_TIMEOUT \n"); + return AM_DMX_ERR_TIMEOUT; + } + + for(i=0; i<cnt; i++) + { + if(fds[i].revents&(POLLIN|POLLERR)) + { + AM_DMX_FILTER_MASK_SET(mask, fids[i]); + } + } + + return AM_SUCCESS; +} + +static AM_ErrorCode_t vbi_read(AM_VBI_Device_t *dev, AM_VBI_Filter_t *filter, uint8_t *buf, int *size) +{ + int fd = (int)filter->drv_data; + int len = *size; + int ret; + struct pollfd pfd; + + if(fd==-1) + return AM_DMX_ERR_NOT_ALLOCATED; + + pfd.events = POLLIN|POLLERR; + pfd.fd = fd; + printf("vbi_read******************pfd.fd = %d \n",pfd.fd); + ret = poll(&pfd, 1, 0); + if(ret<=0) + return AM_DMX_ERR_NO_DATA; + + ret = read(fd, buf, len); + if(ret<=0) + { + if(errno==ETIMEDOUT) + return AM_DMX_ERR_TIMEOUT; + AM_DEBUG( "read demux failed (%s) %d", strerror(errno), errno); + return AM_DMX_ERR_SYS; + } + + *size = ret; + return AM_SUCCESS; +} + +static AM_ErrorCode_t vbi_set_source(AM_VBI_Device_t *dev, AM_VBI_DMX_Source_t src) +{ + char buf[32]; + char *cmd; + + snprintf(buf, sizeof(buf), "/sys/class/stb/demux%d_source", dev->dev_no); + + switch(src) + { + case DUAL_FD1: + cmd = "/dev/vbi"; + break; + case DUAL_FD2: + cmd = "/dev/vbi1"; + break; + } + +return AM_DMX_ERR_CANNOT_OPEN_DEV; +} + diff --git a/ntsc_decode/ntsc_dmx/test/Android.mk b/ntsc_decode/ntsc_dmx/test/Android.mk new file mode 100755 index 0000000..938aa40 --- a/dev/null +++ b/ntsc_decode/ntsc_dmx/test/Android.mk @@ -0,0 +1,17 @@ +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_SRC_FILES:=vbi_test.c +LOCAL_SHARED_LIBRARIES+= libzvbi libntsc_decode + + +LOCAL_C_INCLUDES:=$(LOCAL_PATH)/../../../src \ + $(LOCAL_PATH)/../ \ + $(LOCAL_PATH)/../include + +LOCAL_MODULE:= vbi_test +LOCAL_MODULE_TAGS := optional +LOCAL_ARM_MODE := arm +LOCAL_CFLAGS+=-D_REENTRANT -D_GNU_SOURCE -DENABLE_DVB=1 -DENABLE_V4L=1 -DENABLE_V4L2=1 -DHAVE_ICONV=1 -DPACKAGE=\"zvbi\" -DVERSION=\"0.2.33\" -DANDROID -DHAVE_GETOPT_LONG=1 +LOCAL_SHARED_LIBRARIES += libicuuc liblog +include $(BUILD_EXECUTABLE) diff --git a/ntsc_decode/ntsc_dmx/test/vbi_test.c b/ntsc_decode/ntsc_dmx/test/vbi_test.c new file mode 100755 index 0000000..95353a0 --- a/dev/null +++ b/ntsc_decode/ntsc_dmx/test/vbi_test.c @@ -0,0 +1,209 @@ +#include <stdio.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <fcntl.h> +#include <string.h> +#include <errno.h> +#include <dlfcn.h> +#include <sys/mman.h> +#include <pthread.h> +#include <sched.h> +#include <signal.h> +#include <stdio.h> +#include <vbi_dmx.h> + +#define VBI_IOC_MAGIC 'X' + + +#define VBI_IOC_CC_EN _IO (VBI_IOC_MAGIC, 0x01) +#define VBI_IOC_CC_DISABLE _IO (VBI_IOC_MAGIC, 0x02) +#define VBI_IOC_SET_FILTER _IOW(VBI_IOC_MAGIC, 0x03, int) +#define VBI_IOC_S_BUF_SIZE _IOW(VBI_IOC_MAGIC, 0x04, int) +#define VBI_IOC_START _IO (VBI_IOC_MAGIC, 0x05) +#define VBI_IOC_STOP _IO (VBI_IOC_MAGIC, 0x06) +#define DECODER_VBI_VBI_SIZE 0x1000 + + + + +static unsigned char fd1_closed = 0 , fd2_closed = 0; +static unsigned int buf_size1 = 1024; +static unsigned int buf_size2 = 1024; +static unsigned int cc_type1 = 1; +static unsigned int cc_type2 = 4; +static unsigned int exit_cnt1 = 20; +static unsigned int exit_cnt2 = 30; +static int afe_fd1 = -1,afe_fd2 = -1; +FILE *wr_fp; +char vbuf_addr1[2000]; +char vbuf_addr2[2000]; +#define DUAL_FD1 + +int main(int argc, char *argv[]) +{ + demux_vbi_start(); + return 0; + int ret = 0; + unsigned int i = 0; + pthread_t pid = 0; + + + char name_buf[3] = {0}; + + fd_set rds1,rds2; + struct timeval tv1,tv2; + +#if defined(DUAL_FD1) + afe_fd1 = open("/dev/vbi", O_RDWR|O_NONBLOCK); + if (afe_fd1 < 0) { + printf("open device 1 file Error!!! \n"); + return -1; + } + printf("open device 1 file \n"); +#endif +#if defined(DUAL_FD2) + afe_fd2 = open("/dev/vbi", O_RDWR|O_NONBLOCK); + if (afe_fd2 < 0) { + printf("open device 2 file Error!!! \n"); + return -1; + } + printf("open device 2 file \n"); +#endif +//while (1) { + //ioctl(afe_fd, VBI_IOC_CC_EN); + //sleep(2); + //printf("input cc type value:\n"); + //scanf("%d", &cc_type); + //printf("input cc type1 is:%d \n", cc_type1); +#if defined(DUAL_FD1) + ret = ioctl(afe_fd1, VBI_IOC_S_BUF_SIZE, &buf_size1); + if (ret < 0) { + printf("set afe_fd1 ioctl VBI_IOC_S_BUF_SIZE Error!!! \n"); + return 0; + } + //printf("set afe_fd1 ioctl VBI_IOC_S_BUF_SIZE \n"); + + ret = ioctl(afe_fd1, VBI_IOC_SET_FILTER, &cc_type1);//0,1 + if (ret < 0) { + printf("set afe_fd1 ioctl VBI_IOC_SET_FILTER Error!!! \n"); + return 0; + } + //printf("set afe_fd1 ioctl VBI_IOC_SET_FILTER \n"); + + ret = ioctl(afe_fd1, VBI_IOC_START); + if (ret < 0) { + printf("set afe_fd1 ioctl VBI_IOC_START Error!!! \n"); + return 0; + } + //printf("set afe_fd1 ioctl VBI_IOC_START \n"); + //ioctl(afe_fd1, VBI_IOC_STOP); + // close(afe_fd1); + /// printf(" close afe !!!.\n"); +#endif +#if defined(DUAL_FD2) + ret = ioctl(afe_fd2, VBI_IOC_S_BUF_SIZE, &buf_size2); + if (ret < 0) { + printf("set afe_fd2 ioctl VBI_IOC_S_BUF_SIZE Error!!! \n"); + return 0; + } + // printf("set afe_fd2 ioctl VBI_IOC_S_BUF_SIZE \n"); + + ret = ioctl(afe_fd2, VBI_IOC_SET_FILTER, &cc_type2); + if (ret < 0) { + printf("set afe_fd2 ioctl VBI_IOC_SET_FILTER Error!!! \n"); + return 0; + } + + //printf("set afe_fd2 ioctl VBI_IOC_SET_FILTER \n"); + ret = ioctl(afe_fd2, VBI_IOC_START); + if (ret < 0) { + printf("set afe_fd2 ioctl VBI_IOC_START Error!!! \n"); + return 0; + } + //printf("set afe_fd2 ioctl VBI_IOC_START \n"); +#endif + + while (1) { + + //printf("input exit_cnt, zero for exit:\n"); + //scanf("%d", &exit_cnt); + FD_ZERO(&rds1); + FD_SET(afe_fd1, &rds1); + /* Wait up to five seconds. */ + tv1.tv_sec = 1; + tv1.tv_usec = 0; + + + printf("\n input exit_cnt1 is:%d \n", exit_cnt1); + if (exit_cnt1 == 0) { + if (!fd1_closed) { + fd1_closed = 1; + ioctl(afe_fd1, VBI_IOC_STOP); + close(afe_fd1); + printf("exit_cnt1 is :%d eixt buffer capture function!!!.\n", exit_cnt1); + } + #if defined(DUAL_FD2) + if (exit_cnt2 != 0) + goto fd2; + else + #endif + return 0; + } + + ret = select(afe_fd1 + 1, &rds1, NULL, NULL, &tv1); + if(ret < 0) { + printf("afe_fd1 Read data Faild!......\n"); + break; + } else if(ret == 0) { + printf("afe_fd1 Read data Device Timeout!......\n"); + exit_cnt1--; + //continue; + } else if (FD_ISSET(afe_fd1, &rds1)) { + /* write data to file */ + ret = read(afe_fd1, vbuf_addr1, 5); + if (ret <= 0) { + printf("afe_fd1 read file error: ret=%x!!!! \n", ret); + //close(afe_fd); + //return 0; + } else { + printf("\n afe_fd1 read %2d bytes, exit_cnt1:%2d \n",ret, exit_cnt1); + for (i=0; i<ret; i++) { + printf("0x%02x,",vbuf_addr1[i]); + if ((i > 0) && ((i+1)%8 == 0)){ + printf("\n"); + } + } + exit_cnt1--; + //printf(" \nafe_fd1 finish read 5 buffer data \n"); + } + } + } + fb: + return 0; + +} + +static void dump_bytes(int dev_no, int fid, const uint8_t *data, int len, void *user_data){ + printf("dump_bytes"); +} +void demux_vbi_start(){ + int fid; + AM_DMX_OpenPara_t para; + memset(¶, 0, sizeof(para)); + printf("*******************************\n\n"); + if( AM_NTSC_DMX_Open(VBI_DEV_NO, ¶) != AM_SUCCESS) { + printf("###############AM_DMX_Open fail!\n\n"); + } + + AM_NTSC_DMX_AllocateFilter(VBI_DEV_NO, &fid); + AM_NTSC_DMX_SetCallback(VBI_DEV_NO, fid, dump_bytes, NULL); + + AM_NTSC_DMX_SetBufferSize(VBI_DEV_NO, fid, 1024); + AM_NTSC_DMX_StartFilter(VBI_DEV_NO, fid); + + sleep(100); + +} + diff --git a/ntsc_decode/test/Android.mk b/ntsc_decode/test/Android.mk index 619f428..a7e5c71 100755 --- a/ntsc_decode/test/Android.mk +++ b/ntsc_decode/test/Android.mk @@ -1,12 +1,15 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) -LOCAL_SRC_FILES:=decode.c \ +LOCAL_SRC_FILES:=caption.c \ ../sliced1.c LOCAL_SHARED_LIBRARIES+= libzvbi -LOCAL_C_INCLUDES:=$(LOCAL_PATH)/../../src \ - $(LOCAL_PATH)/../ + +LOCAL_C_INCLUDES:=$(LOCAL_PATH)/../src \ + $(LOCAL_PATH)/ \ + $(LOCAL_PATH)/ntsc_dmx/ \ + $(LOCAL_PATH)/ntsc_dmx/include LOCAL_MODULE:= xds_decode LOCAL_MODULE_TAGS := optional diff --git a/ntsc_decode/test/caption.c b/ntsc_decode/test/caption.c new file mode 100755 index 0000000..def1f99 --- a/dev/null +++ b/ntsc_decode/test/caption.c @@ -0,0 +1,943 @@ +/* + * libzvbi test + * + * Copyright (C) 2000, 2001 Michael H. Schimek + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +/* $Id: caption.c,v 1.19 2008/03/01 07:37:20 mschimek Exp $ */ + +#undef NDEBUG + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <unistd.h> + +#ifndef X_DISPLAY_MISSING + +//#include <X11/Xlib.h> +//#include <X11/keysym.h> +//#include <X11/Xutil.h> + +#include "vbi.h" +#include "exp-gfx.h" +#include "hamm.h" +#include "dvb_demux.h" +#include "sliced.h" +#include "sliced1.h" +#define XDS_SEP_DEBUG(x) /* x */ x +vbi_decoder * vbi; +vbi_pgno pgno = -1; +vbi_dvb_demux * dx; + +/* + * Rudimentary render code for CC test. + * Attention: RGB 5:6:5 little endian only. + */ + +#define DISP_WIDTH 640 +#define DISP_HEIGHT 480 + +#define CELL_WIDTH 16 +#define CELL_HEIGHT 26 + +//Display * display; +int screen; +//Colormap cmap; +//Window window; +//GC gc; +//XEvent event; +//XImage * ximage; +uint32_t * ximgdata; + +int shift = 0, step = 3; +int sh_first, sh_last; + +vbi_rgba row_buffer[64 * CELL_WIDTH * CELL_HEIGHT]; + +#define COLORKEY 0x80FF80 /* where video looks through */ + +#define RGB565(rgba) \ + (((((rgba) >> 16) & 0xF8) << 8) | ((((rgba) >> 8) & 0xFC) << 3) \ + | (((rgba) & 0xF8) >> 3)) + +static void +draw_video (int x0, + int y0, + int w, + int h) +{ + uint32_t *canvas = ximgdata + x0 + y0 * DISP_WIDTH; + int x, y; + + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) + canvas[x] = RGB565(COLORKEY); + canvas += DISP_WIDTH; + } +} + +static void +draw_blank (int column, + int width) +{ + vbi_rgba *canvas = row_buffer + column * CELL_WIDTH; + int x, y; + + for (y = 0; y < CELL_HEIGHT; y++) { + for (x = 0; x < CELL_WIDTH * width; x++) + canvas[x] = COLORKEY; + canvas += sizeof(row_buffer) / sizeof(row_buffer[0]) + / CELL_HEIGHT; + } +} + +//* Not exactly efficient, but this is only a test +static void +draw_row (uint32_t * canvas, + vbi_page * pg, + int row) +{ + int i, j, num_tspaces = 0; + vbi_rgba *s = row_buffer; + XDS_SEP_DEBUG(printf("draw_row = %d\n",row)); + for (i = 0; i < pg->columns; ++i) { + XDS_SEP_DEBUG(printf("%02x ", unicode_ccfont2 (pg->text[row * pg->columns + i].unicode, pg->text[row * pg->columns + i].->italic))); + if (pg->text[row * pg->columns + i].opacity + == VBI_TRANSPARENT_SPACE) { + num_tspaces++; + continue; + } + + if (num_tspaces > 0) { + draw_blank(i - num_tspaces, num_tspaces); + num_tspaces = 0; + } + + vbi_draw_cc_page_region (pg, VBI_PIXFMT_RGBA32_LE, + row_buffer + i * CELL_WIDTH, + sizeof(row_buffer) / CELL_HEIGHT, + i, row, 1, 1); + } + + if (num_tspaces > 0) + draw_blank(i - num_tspaces, num_tspaces); + + XDS_SEP_DEBUG(printf("\npg->columns * CELL_WIDTH= %d\n",pg->columns * CELL_WIDTH)); + return; + for (i = 0; i < CELL_HEIGHT; i++) { + for (j = 0; j < pg->columns * CELL_WIDTH; j++){ + canvas[j] = RGB565(s[j]); + } + s += sizeof(row_buffer) / sizeof(row_buffer[0]) / CELL_HEIGHT; + + canvas += DISP_WIDTH; + } +} + +static void +bump (int n, + vbi_bool draw) +{ + uint32_t *canvas = ximgdata + 45 * DISP_WIDTH; + XDS_SEP_DEBUG(printf("bump")); + return; + if (shift < n) + n = shift; + + if (shift <= 0 || n <= 0) + return; + + memmove (canvas + (sh_first * CELL_HEIGHT) * DISP_WIDTH, + canvas + (sh_first * CELL_HEIGHT + n) * DISP_WIDTH, + ((sh_last - sh_first + 1) * CELL_HEIGHT - n) + * DISP_WIDTH * 2); + + //if (draw) + // XPutImage (display, window, gc, ximage, + // 0, 0, 0, 0, DISP_WIDTH, DISP_HEIGHT); + + shift -= n; +} + +static void +render (vbi_page * pg, + int row) +{ + //* ushort *canvas = ximgdata + 48 + 45 * DISP_WIDTH; + XDS_SEP_DEBUG(printf("render row %d\n",row)); + if (shift > 0) { + bump(shift, FALSE); + draw_video (48, 45 + sh_last * CELL_HEIGHT, + DISP_WIDTH - 48, CELL_HEIGHT); + } + XDS_SEP_DEBUG(printf("render draw_row %d\n",ximgdata + 48 + (45 + row * CELL_HEIGHT) * DISP_WIDTH)); + draw_row (ximgdata + 48 + (45 + row * CELL_HEIGHT) * DISP_WIDTH, + pg, row); + + //XPutImage (display, window, gc, ximage, + // 0, 0, 0, 0, DISP_WIDTH, DISP_HEIGHT); +} +/* +static void +clear (vbi_page * pg) +{ + pg = pg; + + draw_video (0, 0, DISP_WIDTH, DISP_HEIGHT); + + XPutImage (display, window, gc, ximage, + 0, 0, 0, 0, DISP_WIDTH, DISP_HEIGHT); +} + +static void +roll_up (vbi_page * pg, + int first_row, + int last_row) +{ + ushort scol, *canvas = ximgdata + 45 * DISP_WIDTH; + vbi_rgba col; + int i, j; + +#if 1 //* soft + + sh_first = first_row; + sh_last = last_row; + shift = 26; + bump(step, FALSE); + + canvas += 48 + (((last_row * CELL_HEIGHT) + CELL_HEIGHT - step) + * DISP_WIDTH); + col = pg->color_map[pg->text[last_row * pg->columns].background]; + scol = RGB565 (col); + + for (j = 0; j < step; ++j) { + if (pg->text[last_row * pg->columns].opacity + == VBI_TRANSPARENT_SPACE) { + for (i = 0; i < CELL_WIDTH * pg->columns; ++i) + canvas[i] = RGB565 (COLORKEY); + } else { + for (i = 0; i < CELL_WIDTH * pg->columns; ++i) + canvas[i] = scol; + } + + canvas += DISP_WIDTH; + } + +#else //* at once + + memmove (canvas + first_row * CELL_HEIGHT * DISP_WIDTH, + canvas + (first_row + 1) * CELL_HEIGHT * DISP_WIDTH, + (last_row - first_row) * CELL_HEIGHT * DISP_WIDTH * 2); + + draw_video (48, 45 + last_row * CELL_HEIGHT, + DISP_WIDTH - 48, CELL_HEIGHT); + +#endif + + XPutImage (display, window, gc, ximage, + 0, 0, 0, 0, DISP_WIDTH, DISP_HEIGHT); +} + +static void +xevent (int nap_usec); +*/ +static void +cc_handler (vbi_event * ev, + void * user_data) +{ + + printf("cc_handler\n"); + vbi_page page; + vbi_bool success; + int row; + + user_data = user_data; + + if (pgno != -1 && ev->ev.caption.pgno != pgno) + return; + + /* Fetching & rendering in the handler + is a bad idea, but this is only a test */ + + success = vbi_fetch_cc_page (vbi, &page, ev->ev.caption.pgno, TRUE); + assert (success); + XDS_SEP_DEBUG(printf("cc_handler***********success = %d\n",success)); +#if 1 /* optional */ + if (abs (page.dirty.roll) > page.rows) { + XDS_SEP_DEBUG(printf("clear")); + //clear (&page); + } else if (page.dirty.roll == -1) { + XDS_SEP_DEBUG(printf("roll_up")); + //roll_up (&page, page.dirty.y0, page.dirty.y1); + } else { +#endif + + for (row = page.dirty.y0; row <= page.dirty.y1; ++row) + render (&page, row); + } + + vbi_unref_page (&page); +} + + + + + + + + + +static void +xds_handler (vbi_event * ev, + void * user_data) +{ + + printf("xds_handler\n"); + vbi_page page; + vbi_bool success; + if(ev == NULL) + return; + + + vbi_program_info * prog_info = ev->ev.prog_info; + + if(prog_info->rating_auth != VBI_RATING_AUTH_NONE) + { + printf("prog_info->rating_auth = %d\n",prog_info->rating_auth ); + + if(prog_info->rating_auth == VBI_RATING_AUTH_MPAA) + XDS_SEP_DEBUG(printf("result*******************VBI_RATING_AUTH_MPAA\n")); + if(prog_info->rating_auth == VBI_RATING_AUTH_TV_US) + XDS_SEP_DEBUG(printf("result*******************VBI_RATING_AUTH_TV_US\n")); + if(prog_info->rating_auth == VBI_RATING_AUTH_TV_CA_EN) + XDS_SEP_DEBUG(printf("result*******************VBI_RATING_AUTH_TV_CA_EN\n")); + if(prog_info->rating_auth == VBI_RATING_AUTH_TV_CA_FR) + XDS_SEP_DEBUG(printf("result*******************VBI_RATING_AUTH_TV_CA_FR\n")); + if(prog_info->rating_auth == VBI_RATING_AUTH_NONE) + XDS_SEP_DEBUG(printf("result*******************VBI_RATING_AUTH_NONE\n")); + + if (prog_info->rating_dlsv == VBI_RATING_D) + XDS_SEP_DEBUG(printf("result*******************VBI_RATING_D\n")); + if (prog_info->rating_dlsv == VBI_RATING_L) + XDS_SEP_DEBUG(printf("result*******************VBI_RATING_L\n")); + if (prog_info->rating_dlsv == VBI_RATING_S) + XDS_SEP_DEBUG(printf("result*******************VBI_RATING_S\n")); + if (prog_info->rating_dlsv == VBI_RATING_V) + XDS_SEP_DEBUG(printf("result*******************VBI_RATING_V\n")); + XDS_SEP_DEBUG(printf("result*******************prog_info->rating_id = %d\n",prog_info->rating_id )); + + } + +} + + + +static void +reset (void) +{ + vbi_page page; + vbi_bool success; + int row; + + success = vbi_fetch_cc_page (vbi, &page, pgno, TRUE); + assert (success); + + for (row = 0; row <= page.rows; ++row) + render (&page, row); + + vbi_unref_page (&page); +} + +/* + * X11 stuff + */ +/* +static void +xevent (int nap_usec) +{ + while (XPending (display)) { + XNextEvent (display, &event); + + switch (event.type) { + case KeyPress: + { + int c = XLookupKeysym (&event.xkey, 0); + + switch (c) { + case 'q': + case 'c': + exit (EXIT_SUCCESS); + + case '1' ... '8': + pgno = c - '1' + 1; + reset (); + return; + + case XK_F1 ... XK_F8: + pgno = c - XK_F1 + 1; + reset (); + return; + } + + break; + } + + case Expose: + XPutImage (display, window, gc, ximage, + 0, 0, 0, 0, DISP_WIDTH, DISP_HEIGHT); + break; + + case ClientMessage: + exit (EXIT_SUCCESS); + } + } + + bump (step, TRUE); + + usleep (nap_usec / 4); +} +*/ +static vbi_bool +init_window (int ac, + char ** av) +{ + //Atom delete_window_atom; + //XWindowAttributes wa; + int i; + + ac = ac; + av = av; + + //if (!(display = XOpenDisplay (NULL))) { + // return FALSE; + //} + + //screen = DefaultScreen (display); + //cmap = DefaultColormap (display, screen); + + //window = XCreateSimpleWindow (display, + // RootWindow (display, screen), + // 0, 0, + // DISP_WIDTH, DISP_HEIGHT, + // 2, + // 0xffffffff, + // 0x00000000); + //if (!window) { + // return FALSE; + //} + + //XGetWindowAttributes (display, window, &wa); + + //if (16 != wa.depth) { + // fprintf (stderr, "Can only run at " + // "color depth 16 (5:6:5) LE\n"); + // return FALSE; + //} + + if (!(ximgdata = malloc (DISP_WIDTH * DISP_HEIGHT * 2))) { + return FALSE; + } + + for (i = 0; i < DISP_WIDTH * DISP_HEIGHT; ++i) + ximgdata[i] = RGB565 (COLORKEY); + + //ximage = XCreateImage(display, + // DefaultVisual (display, screen), + // DefaultDepth (display, screen), + // ZPixmap, 0, (char *) ximgdata, + // DISP_WIDTH, DISP_HEIGHT, + // 8, 0); + //if (!ximage) { + // return FALSE; + //} + + //delete_window_atom = XInternAtom (display, "WM_DELETE_WINDOW", False); + + //XSelectInput (display, window, + // KeyPressMask | + // ExposureMask | + // StructureNotifyMask); + //XSetWMProtocols (display, window, &delete_window_atom, 1); + //XStoreName (display, window, "Caption Test - [Q], [F1]..[F8]"); + + //gc = XCreateGC (display, window, 0, NULL); + + //XMapWindow (display, window); + + //XSync (display, False); + + //XPutImage (display, window, gc, ximage, + // 0, 0, 0, 0, DISP_WIDTH, DISP_HEIGHT); + + return TRUE; +} + +static vbi_bool +decode_frame (const vbi_sliced * sliced, + unsigned int n_lines, + const uint8_t * raw, + const vbi_sampling_par *sp, + double sample_time, + int64_t stream_time) +{ + printf("decode_frame\n"); + raw = raw; + sp = sp; + stream_time = stream_time; /* unused */ + + vbi_decode (vbi, sliced, n_lines, sample_time); + + /* xevent (1e6 / 30); */ + + return TRUE; +} + +/* + * Feed artificial caption + */ + +static void +cmd (unsigned int n) +{ + vbi_sliced sliced; + static double time = 0.0; + + sliced.id = VBI_SLICED_CAPTION_525; + sliced.line = 21; + sliced.data[0] = vbi_par8 (n >> 8); + sliced.data[1] = vbi_par8 (n & 0x7F); + + vbi_decode (vbi, &sliced, 1, time); + + //xevent (33333); + + time += 1 / 29.97; +} + +static void +printc (int c) +{ + cmd (c * 256 + 0x80); + + //xevent (33333); +} + +static void +prints (const char * s) +{ + for (; s[0] && s[1]; s += 2) + cmd (s[0] * 256 + s[1]); + + if (s[0]) + cmd (s[0] * 256 + 0x80); + + //xevent (33333); +} + +enum { + white, green, red, yellow, blue, cyan, magenta, black +}; + +static int +mapping_row [] = { + 2, 3, 4, 5, 10, 11, 12, 13, 14, 15, 0, 6, 7, 8, 9, -1 +}; + +#define italic 7 +#define underline 1 +#define opaque 0 +#define semi_transp 1 + +#define BACKG(bg, t) \ + (cmd (0x2000), cmd (0x1020 + ((ch & 1) << 11) + (bg << 1) + t)) +#define PREAMBLE(r, fg, u) \ + cmd (0x1040 + ((ch & 1) << 11) + ((mapping_row[r] & 14) << 7) \ + + ((mapping_row[r] & 1) << 5) + (fg << 1) + u) +#define INDENT(r, fg, u) \ + cmd (0x1050 + ((ch & 1) << 11) + ((mapping_row[r] & 14) << 7) \ + + ((mapping_row[r] & 1) << 5) + ((fg / 4) << 1) + u) +#define MIDROW(fg, u) cmd (0x1120 + ((ch & 1) << 11) + (fg << 1) + u) +#define SPECIAL_CHAR(n) cmd (0x1130 + ((ch & 1) << 11) + n) +#define CCODE(code, ch) (code + ((ch & 1) << 11) + ((ch & 2) << 7)) +#define RESUME_CAPTION cmd (CCODE (0x1420, ch)) +#define BACKSPACE cmd (CCODE (0x1421, ch)) +#define DELETE_EOR cmd (CCODE (0x1424, ch)) +#define ROLL_UP(rows) cmd (CCODE (0x1425, ch) + rows - 2) +#define FLASH_ON cmd (CCODE (0x1428, ch)) +#define RESUME_DIRECT cmd (CCODE (0x1429, ch)) +#define TEXT_RESTART cmd (CCODE (0x142A, ch)) +#define RESUME_TEXT cmd (CCODE (0x142B, ch)) +#define END_OF_CAPTION cmd (CCODE (0x142F, ch)) +#define ERASE_DISPLAY cmd (CCODE (0x142C, ch)) +#define CR cmd (CCODE (0x142D, ch)) +#define ERASE_HIDDEN cmd (CCODE (0x142E, ch)) +#define TAB(t) cmd (CCODE (0x1720, ch) + t) +#define TRANSP (cmd (0x2000), cmd (0x172D + ((ch & 1) << 11))) +#define BLACK(u) (cmd (0x2000), cmd (0x172E + ((ch & 1) << 11) + u)) + +static void +PAUSE (unsigned int n_frames) +{ + while (n_frames-- > 0){ + //xevent (33333); + } +} + +static void +hello_world (void) +{ + int ch = 0; + int i; + + pgno = -1; + + prints (" HELLO WORLD! "); + PAUSE (30); + + ch = 4; + TEXT_RESTART; + prints ("Character set - Text 1"); + CR; CR; + for (i = 32; i <= 127; i++) { + printc (i); + if ((i & 15) == 15) + CR; + } + MIDROW (italic, 0); + for (i = 32; i <= 127; i++) { + printc (i); + if ((i & 15) == 15) + CR; + } + MIDROW (white, underline); + for (i = 32; i <= 127; i++) { + printc (i); + if ((i & 15) == 15) + CR; + } + MIDROW (white, 0); + prints ("Special: "); + for (i = 0; i <= 15; i++) { + SPECIAL_CHAR (i); + } + CR; + prints ("DONE - Text 1 "); + PAUSE (50); + + ch = 5; + TEXT_RESTART; + prints ("Styles - Text 2"); + CR; CR; + MIDROW (white, 0); prints ("WHITE"); CR; + MIDROW (red, 0); prints ("RED"); CR; + MIDROW (green, 0); prints ("GREEN"); CR; + MIDROW (blue, 0); prints ("BLUE"); CR; + MIDROW (yellow, 0); prints ("YELLOW"); CR; + MIDROW (cyan, 0); prints ("CYAN"); CR; + MIDROW (magenta, 0); prints ("MAGENTA"); BLACK (0); CR; + BACKG (white, opaque); prints ("WHITE"); BACKG (black, opaque); CR; + BACKG (red, opaque); prints ("RED"); BACKG (black, opaque); CR; + BACKG (green, opaque); prints ("GREEN"); BACKG (black, opaque); CR; + BACKG (blue, opaque); prints ("BLUE"); BACKG (black, opaque); CR; + BACKG (yellow, opaque); prints ("YELLOW"); BACKG (black, opaque); CR; + BACKG (cyan, opaque); prints ("CYAN"); BACKG (black, opaque); CR; + BACKG (magenta, opaque); prints ("MAGENTA"); BACKG (black, opaque); CR; + TRANSP; + prints (" TRANSPARENT BACKGROUND "); + BACKG (black, opaque); CR; + MIDROW (white, 0); FLASH_ON; + prints (" Flashing Text (if implemented) "); CR; + MIDROW (white, 0); prints ("DONE - Text 2 "); + PAUSE (50); + + ch = 0; + ROLL_UP (2); + ERASE_DISPLAY; + prints (" ROLL-UP TEST "); CR; PAUSE (20); + prints (">> A young Jedi named Darth"); CR; PAUSE (20); + prints ("Vader, who was a pupil of"); CR; PAUSE (20); + prints ("mine until he turned to evil,"); CR; PAUSE (20); + prints ("helped the Empire hunt down"); CR; PAUSE (20); + prints ("and destroy the Jedi Knights."); CR; PAUSE (20); + prints ("He betrayed and murdered your"); CR; PAUSE (20); + prints ("father. Now the Jedi are all"); CR; PAUSE (20); + prints ("but extinct. Vader was seduced"); CR; PAUSE (20); + prints ("by the dark side of the Force."); CR; PAUSE (20); + prints (">> The Force?"); CR; PAUSE (20); + prints (">> Well, the Force is what gives"); CR; PAUSE (20); + prints ("a Jedi his power. It's an energy"); CR; PAUSE (20); + prints ("field created by all living"); CR; PAUSE (20); + prints ("things."); CR; PAUSE (20); + prints ("It surrounds us and penetrates"); CR; PAUSE (20); + prints ("us."); CR; PAUSE (20); + prints ("It binds the galaxy together."); CR; PAUSE (20); + CR; PAUSE (30); + prints (" DONE - Caption 1 "); + PAUSE (30); + + ch = 1; + RESUME_DIRECT; + ERASE_DISPLAY; + MIDROW (yellow, 0); + INDENT (2, 10, 0); prints (" FOO "); CR; + INDENT (3, 10, 0); prints (" MIKE WAS HERE "); CR; PAUSE (20); + MIDROW (red, 0); + INDENT (6, 13, 0); prints (" AND NOW... "); CR; + INDENT (8, 13, 0); prints (" HE'S HERE "); CR; PAUSE (20); + PREAMBLE (12, cyan, 0); + prints ("01234567890123456789012345678901234567890123456789"); CR; + MIDROW (white, 0); + prints (" DONE - Caption 2 "); CR; + PAUSE (30); +} + +int +main (int argc, + char ** argv) +{ + + unsigned char pBuffer[] ={ + 0x00,0x01,0x02,0x00,0x15,0x00,0x00,0x00, + 0x00,0x01,0x02,0x00,0x15,0x00,0x01,0x05, + 0x00,0x01,0x02,0x00,0x15,0x00,0x41,0x40, + 0x00,0x01,0x02,0x00,0x15,0x00,0x0f,0x6a, + 0x00,0x01,0x02,0x00,0x15,0x00,0x00,0x00, + 0x00,0x01,0x02,0x00,0x15,0x00,0x00,0x00, + 0x00,0x01,0x02,0x00,0x15,0x00,0x15,0x2c, + 0x00,0x01,0x02,0x00,0x15,0x00,0x15,0x2e, + 0x00,0x01,0x02,0x00,0x15,0x00,0x15,0x20, + 0x00,0x01,0x02,0x00,0x15,0x00,0x16,0x46, + 0x00,0x01,0x02,0x00,0x15,0x00,0x20,0x20, + 0x00,0x01,0x02,0x00,0x15,0x00,0x10,0x22, + 0x00,0x01,0x02,0x00,0x15,0x00,0x43,0x6c, + 0x00,0x01,0x02,0x00,0x15,0x00,0x6f,0x73, + 0x00,0x01,0x02,0x00,0x15,0x00,0x65,0x64, + 0x00,0x01,0x02,0x00,0x15,0x00,0x20,0x43, + 0x00,0x01,0x02,0x00,0x15,0x00,0x61,0x70, + 0x00,0x01,0x02,0x00,0x15,0x00,0x74,0x69, + 0x00,0x01,0x02,0x00,0x15,0x00,0x6f,0x6e , + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x2f, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x41,0x00, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x45,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x4f,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x75,0x00, + + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x2f, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x41,0x00, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x45,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x4f,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x75,0x00, + + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x2f, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x41,0x00, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x45,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x4f,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x75,0x00, + + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x2f, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x41,0x00, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x45,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x4f,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x75,0x00, + }; + + unsigned char pBuffer11[] ={ 1,21, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x2f, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1c,0x29, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1d,0x6a, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x41,0x00, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x20, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x45,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x21, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x4f,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x22, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x23, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x55,0x00, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x1a,0x24, + 0x00,0x00,0x02,0x00,0x1c,0x01,0x75,0x00, + + }; + + + int length = N_ELEMENTS (pBuffer); + + + vbi_bool success; + + //if (!init_window (argc, argv)) + // exit (EXIT_FAILURE); + + vbi = vbi_decoder_new (); + + assert (NULL != vbi); + + success = vbi_event_handler_add (vbi, VBI_EVENT_CAPTION, + cc_handler, /* used_data */ NULL); + assert (success); + + + success = vbi_event_handler_add (vbi, VBI_EVENT_ASPECT | VBI_EVENT_PROG_INFO, + xds_handler, /* used_data */ NULL); + assert (success); + + + + + //if (isatty (STDIN_FILENO)) { + // hello_world (); + //} else { + struct stream *st; + + printf("read_stream_new\n"); + st = read_stream_new (pBuffer,length, + FILE_FORMAT_SLICED, + 0, + decode_frame); + + //st = read_stream_new (/* filename: stdin */ NULL, + // FILE_FORMAT_SLICED, + // /* ts_pid */ 0, + // decode_frame); + stream_loop (st); + stream_delete (st); + //} + + printf ("Done.\n"); + + //for (;;) + // xevent (33333); + + vbi_decoder_delete (vbi); + + exit (EXIT_SUCCESS); +} + +#else /* X_DISPLAY_MISSING */ + +int +main (int argc, + char ** argv) +{ + printf ("Could not find X11 or has been disabled " + "at configuration time\n"); + exit(EXIT_FAILURE); +} + +#endif |