2 * Copyright (c) 2002 Billy Biggs <vektor@dumbterm.net>.
3 * Copyright (c) 2002 Doug Bell <drbell@users.sourceforge.net>.
5 * Modified and adapted to GStreamer by
6 * David I. Lehn <dlehn@users.sourceforge.net>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or (at
11 * your option) any later version.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
34 /*#include "osdtools.h"*/
35 /*#include "speedy.h"*/
37 #include "vbiscreen.h"
38 #include "gstvbidec.h"
52 typedef struct osd_string_s osd_string_t;
63 osd_string_new (char *c, int s, int w, int h, int a, void *user_data)
67 os = (osd_string_t *) malloc (sizeof (osd_string_t));
72 os->r = os->g = os->b = 0;
74 os->vbidec = (GstVBIDec *) user_data;
79 osd_string_show_text (osd_string_t * os, char *s, int len)
81 /* FIXME: just print data when it gets here */
83 gst_vbidec_show_text (os->vbidec, s, len);
87 osd_string_get_height (osd_string_t * os)
93 osd_string_get_width (osd_string_t * os)
99 osd_string_delete (osd_string_t * os)
105 osd_string_set_colour_rgb (osd_string_t * os, int r, int g, int b)
113 blit_colour_packed422_scanline (unsigned char *d, int w, int luma, int cb,
118 osd_string_visible (osd_string_t * os)
124 osd_string_composite_packed422_scanline (osd_string_t * os, unsigned char *a,
125 unsigned char *b, int w, int x, int y)
132 osd_string_t *line[ROWS];
134 char buffers[ROWS * COLS * 2];
135 char text[2 * ROWS * COLS];
136 char hiddenbuf[COLS];
137 char paintbuf[ROWS * COLS];
139 unsigned int fgcolour;
140 unsigned int bgcolour;
141 int bg_luma, bg_cb, bg_cr;
147 int x, y; /* where to draw console */
148 int width, height; /* the size box we have to draw in */
149 int rowheight, charwidth;
151 int curx, cury; /* cursor position */
152 int rows, cols; /* 32 cols 15 rows */
153 int captions, style; /* CC (1) or Text (0), RU2 RU3 RU4 POP_UP PAINT_ON */
154 int first_line; /* where to start drawing */
156 int top_of_screen; /* a pointer into line[] */
169 vbiscreen_new (int video_width, int video_height,
170 double video_aspect, int verbose, void *user_data)
172 int i = 0, fontsize = FONT_SIZE;
173 vbiscreen_t *vs = (vbiscreen_t *) malloc (sizeof (struct vbiscreen_s));
179 vs->verbose = verbose;
182 vs->frame_width = video_width;
183 vs->frame_height = video_height;
184 vs->frame_aspect = video_aspect;
187 vs->fgcolour = 0xFFFFFFFFU; /* white */
188 vs->bgcolour = 0xFF000000U; /* black */
194 /*vs->fontfile = DATADIR "/FreeMonoBold.ttf"; */
196 vs->fontsize = fontsize;
197 vs->width = video_width;
198 vs->height = video_height;
203 vs->top_of_screen = 0;
205 memset (vs->buffers, 0, 2 * COLS * ROWS);
206 memset (vs->hiddenbuf, 0, COLS);
207 memset (vs->paintbuf, 0, ROWS * COLS);
210 vs->user_data = user_data;
212 vs->line[0] = osd_string_new (vs->fontfile, fontsize, video_width,
213 video_height, video_aspect, user_data);
216 vs->fontfile = "./FreeMonoBold.ttf";
218 vs->line[0] = osd_string_new (vs->fontfile, fontsize,
219 video_width, video_height, video_aspect, user_data);
223 fprintf (stderr, "vbiscreen: Could not find my font (%s)!\n", vs->fontfile);
224 vbiscreen_delete (vs);
228 osd_string_show_text (vs->line[0], "W", 0);
229 vs->rowheight = osd_string_get_height (vs->line[0]);
230 vs->charwidth = osd_string_get_width (vs->line[0]);
231 osd_string_delete (vs->line[0]);
233 for (i = 0; i < ROWS; i++) {
234 vs->line[i] = osd_string_new (vs->fontfile, fontsize,
235 video_width, video_height, video_aspect, user_data);
237 fprintf (stderr, "vbiscreen: Could not allocate a line.\n");
238 vbiscreen_delete (vs);
241 osd_string_set_colour_rgb (vs->line[i],
242 (vs->fgcolour & 0xff0000) >> 16,
243 (vs->fgcolour & 0xff00) >> 8, (vs->fgcolour & 0xff));
244 osd_string_show_text (vs->line[i], " ", 0);
246 memset (vs->text, 0, 2 * ROWS * COLS);
251 blank_screen (vbiscreen_t * vs)
256 fprintf (stderr, "in blank\n");
257 for (i = 0; i < ROWS; i++) {
258 osd_string_show_text (vs->line[i], " ", 0);
263 clear_screen (vbiscreen_t * vs)
270 base = vs->top_of_screen * COLS;
271 for (i = 0; i < ROWS * COLS; i++) {
274 base %= 2 * ROWS * COLS;
280 clear_hidden_roll (vbiscreen_t * vs)
284 memset (vs->hiddenbuf, 0, COLS);
288 clear_hidden_pop (vbiscreen_t * vs)
292 memset (vs->buffers + vs->curbuffer * COLS * ROWS, 0, COLS * ROWS);
296 clear_hidden_paint (vbiscreen_t * vs)
300 memset (vs->paintbuf, 0, COLS * ROWS);
304 clear_displayed_pop (vbiscreen_t * vs)
308 memset (vs->buffers + (vs->curbuffer ^ 1) * COLS * ROWS, 0, COLS * ROWS);
312 vbiscreen_dump_screen_text (vbiscreen_t * vs)
318 offset = vs->top_of_screen * COLS;
320 fprintf (stderr, "\n 0123456789abcdefghij012345678901");
321 for (i = 0; i < ROWS * COLS; i++) {
323 fprintf (stderr, "\n%.2d ", i / COLS);
324 fprintf (stderr, "%c", vs->text[offset] ? vs->text[offset] : ' ');
326 offset %= 2 * ROWS * COLS;
328 fprintf (stderr, "\n 0123456789abcdefghij012345678901\n ");
329 for (i = 0; i < COLS; i++) {
330 fprintf (stderr, "%c", vs->text[offset] ? vs->text[offset] : ' ');
332 offset %= 2 * ROWS * COLS;
334 fprintf (stderr, "\n 0123456789abcdefghij012345678901\n");
338 update_row_x (vbiscreen_t * vs, int row)
341 int i, j, haschars = 0, base;
347 base = ((vs->top_of_screen + row) % (2 * ROWS)) * COLS;
348 for (j = 0, i = base; i < base + COLS; i++, j++) {
350 text[j] = vs->text[i];
357 osd_string_set_colour_rgb (vs->line[row],
358 (vs->fgcolour & 0xff0000) >> 16,
359 (vs->fgcolour & 0xff00) >> 8, (vs->fgcolour & 0xff));
361 osd_string_show_text (vs->line[row], " ", 0);
363 osd_string_show_text (vs->line[row], text, 51);
369 update_row (vbiscreen_t * vs)
374 update_row_x (vs, vs->cury);
375 //vbiscreen_dump_screen_text( vs );
379 update_all_rows (vbiscreen_t * vs)
386 for (row = 0; row < ROWS; row++) {
387 update_row_x (vs, row);
389 //vbiscreen_dump_screen_text( vs );
393 vbiscreen_delete (vbiscreen_t * vs)
399 copy_row_to_screen (vbiscreen_t * vs, char *row)
403 base = ((vs->top_of_screen + vs->cury) % (2 * ROWS)) * COLS;
404 for (j = 0, i = base; i < base + COLS; j++, i++) {
405 vs->text[i] = row[j];
411 scroll_screen (vbiscreen_t * vs)
415 if (!vs || !vs->captions || !vs->style || vs->style > ROLL_4)
418 start_row = (vs->first_line + vs->top_of_screen) % (2 * ROWS);
420 fprintf (stderr, "start row : %d first line %d\n ", start_row,
423 /* zero out top row */
424 memset ((char *) (vs->text + start_row * COLS), 0, COLS);
425 vs->top_of_screen = (vs->top_of_screen + 1) % (2 * ROWS);
426 vs->curx = vs->indent;
427 update_all_rows (vs);
428 copy_row_to_screen (vs, vs->hiddenbuf);
429 clear_hidden_roll (vs);
434 vbiscreen_set_verbose (vbiscreen_t * vs, int verbose)
436 vs->verbose = verbose;
440 vbiscreen_new_caption (vbiscreen_t * vs, int indent, int ital,
441 unsigned int colour, int row)
446 fprintf (stderr, "indent: %d, ital: %d, colour: 0x%x, row: %d\n", indent,
449 if (0 && vs->captions && vs->style <= ROLL_4 && vs->style) {
450 if (row != vs->cury + 1) {
452 clear_hidden_roll (vs);
454 // scroll_screen( vs );
458 if (vs->style > ROLL_4) {
459 vs->cury = ((row > 0) ? row - 1 : 0);
462 vs->fgcolour = colour;
468 vbiscreen_set_mode (vbiscreen_t * vs, int caption, int style)
473 fprintf (stderr, "in set mode\n");
476 fprintf (stderr, "Caption: %d ", caption);
479 fprintf (stderr, "ROLL 2\n");
482 fprintf (stderr, "ROLL 3\n");
485 fprintf (stderr, "ROLL 4\n");
488 fprintf (stderr, "POP UP\n");
491 fprintf (stderr, "PAINT ON\n");
501 /* captioning mode */
502 /* styles: ru2 ru3 ru4 pop paint
504 if (style != POP_UP && vs->style == POP_UP && !vs->got_eoc) {
505 /* stupid that sometimes they dont send a EOC */
506 vbiscreen_end_of_caption (vs);
513 if (vs->style == style) {
516 vs->first_line = ROWS - (style - 4);
519 fprintf (stderr, "first_line %d\n", vs->first_line);
531 vs->captions = caption;
536 vbiscreen_tab (vbiscreen_t * vs, int cols)
540 if (cols < 0 || cols > 3)
548 vbiscreen_set_colour (vbiscreen_t * vs, unsigned int col)
556 vbiscreen_clear_current_cell (vbiscreen_t * vs)
558 vs->text[((vs->top_of_screen + vs->cury) % (2 * ROWS)) * COLS
559 + vs->curx + vs->indent] = 0;
563 vbiscreen_set_current_cell (vbiscreen_t * vs, char text)
569 base = ((vs->top_of_screen + vs->cury) % (2 * ROWS)) * COLS;
570 if (g_ascii_isprint (text))
571 vs->text[base + vs->curx + vs->indent] = text;
573 vs->text[base + vs->curx + vs->indent] = ' ';
577 vbiscreen_delete_to_end (vbiscreen_t * vs)
584 fprintf (stderr, "in del to end\n");
585 for (i = vs->curx; i < COLS; i++) {
586 vbiscreen_clear_current_cell (vs);
589 vs->curx = COLS - 1; /* is this right ? */
590 if (vs->captions && vs->style && vs->style != POP_UP)
595 vbiscreen_backspace (vbiscreen_t * vs)
600 fprintf (stderr, "in backspace\n");
604 vbiscreen_clear_current_cell (vs);
609 vbiscreen_erase_displayed (vbiscreen_t * vs)
614 fprintf (stderr, "in erase disp\n");
616 if (vs->captions && vs->style && vs->style <= ROLL_4) {
617 clear_hidden_roll (vs);
620 clear_displayed_pop (vs);
625 vbiscreen_erase_non_displayed (vbiscreen_t * vs)
630 fprintf (stderr, "in erase non disp\n");
632 if (vs->captions && vs->style == POP_UP) {
633 memset (vs->buffers + vs->curbuffer * COLS * ROWS + vs->cury * COLS, 0,
635 // clear_hidden_pop( vs );
636 } else if (vs->captions && vs->style && vs->style <= ROLL_4) {
637 clear_hidden_roll (vs);
642 vbiscreen_carriage_return (vbiscreen_t * vs)
647 fprintf (stderr, "in CR\n");
648 if (vs->style != POP_UP) {
649 /* not sure if this is right for text mode */
650 /* in text mode, perhaps a CR on last row clears screen and goes
655 /* keep cursor on bottom for rollup */
656 if (vs->captions && vs->style && vs->style <= ROLL_4)
664 copy_buf_to_screen (vbiscreen_t * vs, char *buf)
671 base = vs->top_of_screen * COLS;
672 for (j = 0, i = 0; i < ROWS * COLS; i++, j++) {
673 vs->text[base] = buf[j];
675 base %= 2 * ROWS * COLS;
677 update_all_rows (vs);
681 vbiscreen_end_of_caption (vbiscreen_t * vs)
687 fprintf (stderr, "in end of caption\n");
689 if (vs->style == PAINT_ON) {
690 copy_buf_to_screen (vs, vs->paintbuf);
691 clear_hidden_paint (vs);
692 } else if (vs->style == POP_UP) {
693 copy_buf_to_screen (vs, vs->buffers + vs->curbuffer * COLS * ROWS);
704 vbiscreen_print (vbiscreen_t * vs, char c1, char c2)
709 fprintf (stderr, "in print (%d, %d)[%c %c]\n", vs->curx, vs->cury, c1, c2);
710 if (vs->captions && vs->style == POP_UP) {
711 /* this all gets displayed at another time */
712 if (vs->curx != COLS - 1) {
713 *(vs->buffers + vs->curx + vs->curbuffer * ROWS * COLS +
714 vs->cury * COLS) = c1;
718 if (vs->curx != COLS - 1 && c2) {
719 *(vs->buffers + vs->curx + vs->curbuffer * ROWS * COLS +
720 vs->cury * COLS) = c2;
723 *(vs->buffers + vs->curx + vs->curbuffer * ROWS * COLS +
724 vs->cury * COLS) = c2;
728 if (vs->captions && vs->style == PAINT_ON) {
729 if (vs->curx != COLS - 1) {
730 vs->paintbuf[vs->curx + vs->cury * COLS] = c1;
734 if (vs->curx != COLS - 1 && c2) {
735 vs->paintbuf[vs->curx + vs->cury * COLS] = c2;
738 vs->paintbuf[vs->curx + vs->cury * COLS] = c2;
742 if (vs->captions && vs->style && vs->style <= ROLL_4) {
743 if (vs->curx != COLS - 1) {
744 vs->hiddenbuf[vs->curx] = c1;
747 vs->hiddenbuf[vs->curx] = c1;
750 if (vs->curx != COLS - 1 && c2) {
751 vs->hiddenbuf[vs->curx] = c2;
754 vs->hiddenbuf[vs->curx] = c2;
760 vbiscreen_reset (vbiscreen_t * vs)
765 clear_hidden_pop (vs);
766 clear_displayed_pop (vs);
767 clear_hidden_roll (vs);
773 vbiscreen_composite_packed422_scanline (vbiscreen_t * vs,
774 unsigned char *output, int width, int xpos, int scanline)
776 int x = 0, y = 0, row = 0, index = 0;
782 if (scanline >= vs->y && scanline < vs->y + vs->height) {
784 if (0 && !vs->captions)
785 blit_colour_packed422_scanline (output + (vs->x * 2), vs->width,
786 vs->bg_luma, vs->bg_cb, vs->bg_cr);
788 index = vs->top_of_screen * COLS;
789 x = (vs->x + vs->charwidth) & ~1;
790 for (row = 0; row < ROWS; row++) {
791 y = vs->y + row * vs->rowheight + vs->rowheight;
792 if (osd_string_visible (vs->line[row])) {
793 if (scanline >= y && scanline < y + vs->rowheight) {
807 if (startx < width) {
810 blit_colour_packed422_scanline (output + (startx * 2),
811 osd_string_get_width (vs->line[row]),
812 vs->bg_luma, vs->bg_cb, vs->bg_cr);
814 osd_string_composite_packed422_scanline (vs->line[row],
815 output + (startx * 2),
816 output + (startx * 2), width - startx, strx, scanline - y);