| /* |
| * Copyright (c) 2002 Billy Biggs <vektor@dumbterm.net>. |
| * Copyright (c) 2002 Doug Bell <drbell@users.sourceforge.net>. |
| * |
| * Modified and adapted to GStreamer by |
| * David I. Lehn <dlehn@users.sourceforge.net> |
| * |
| * 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. |
| */ |
| |
| #ifdef HAVE_CONFIG_H |
| #include "config.h" |
| #endif |
| |
| #include <glib.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <stdarg.h> |
| #include <string.h> |
| #include <ctype.h> |
| #include <unistd.h> |
| /*#include "osdtools.h"*/ |
| /*#include "speedy.h"*/ |
| #include <glib.h> |
| #include "vbiscreen.h" |
| #include "gstvbidec.h" |
| |
| #define ROLL_2 6 |
| #define ROLL_3 7 |
| #define ROLL_4 8 |
| #define POP_UP 9 |
| #define PAINT_ON 10 |
| |
| |
| #define NUM_LINES 15 |
| #define ROWS 15 |
| #define COLS 32 |
| #define FONT_SIZE 20 |
| |
| typedef struct osd_string_s osd_string_t; |
| struct osd_string_s |
| { |
| int width; |
| int height; |
| int r, g, b; |
| int visible; |
| GstVBIDec *vbidec; |
| }; |
| |
| osd_string_t * |
| osd_string_new (char *c, int s, int w, int h, int a, void *user_data) |
| { |
| osd_string_t *os; |
| |
| os = (osd_string_t *) malloc (sizeof (osd_string_t)); |
| if (!os) |
| return NULL; |
| os->width = 0; |
| os->height = 0; |
| os->r = os->g = os->b = 0; |
| os->visible = 1; |
| os->vbidec = (GstVBIDec *) user_data; |
| return os; |
| } |
| |
| void |
| osd_string_show_text (osd_string_t * os, char *s, int len) |
| { |
| /* FIXME: just print data when it gets here */ |
| if (len > 0) { |
| gst_vbidec_show_text (os->vbidec, s, len); |
| } |
| } |
| |
| int |
| osd_string_get_height (osd_string_t * os) |
| { |
| return os->height; |
| } |
| |
| int |
| osd_string_get_width (osd_string_t * os) |
| { |
| return os->width; |
| } |
| |
| void |
| osd_string_delete (osd_string_t * os) |
| { |
| free (os); |
| } |
| |
| void |
| osd_string_set_colour_rgb (osd_string_t * os, int r, int g, int b) |
| { |
| os->r = r; |
| os->g = g; |
| os->b = b; |
| } |
| |
| void |
| blit_colour_packed422_scanline (unsigned char *d, int w, int luma, int cb, |
| int cr) |
| { |
| } |
| |
| int |
| osd_string_visible (osd_string_t * os) |
| { |
| return os->visible; |
| } |
| |
| void |
| osd_string_composite_packed422_scanline (osd_string_t * os, unsigned char *a, |
| unsigned char *b, int w, int x, int y) |
| { |
| } |
| |
| struct vbiscreen_s |
| { |
| |
| osd_string_t *line[ROWS]; |
| |
| char buffers[ROWS * COLS * 2]; |
| char text[2 * ROWS * COLS]; |
| char hiddenbuf[COLS]; |
| char paintbuf[ROWS * COLS]; |
| |
| unsigned int fgcolour; |
| unsigned int bgcolour; |
| int bg_luma, bg_cb, bg_cr; |
| |
| int frame_width; |
| int frame_height; |
| int frame_aspect; |
| |
| int x, y; /* where to draw console */ |
| int width, height; /* the size box we have to draw in */ |
| int rowheight, charwidth; |
| |
| int curx, cury; /* cursor position */ |
| int rows, cols; /* 32 cols 15 rows */ |
| int captions, style; /* CC (1) or Text (0), RU2 RU3 RU4 POP_UP PAINT_ON */ |
| int first_line; /* where to start drawing */ |
| int curbuffer; |
| int top_of_screen; /* a pointer into line[] */ |
| int indent; |
| int got_eoc; |
| int scroll; |
| |
| char *fontfile; |
| int fontsize; |
| int verbose; |
| |
| void *user_data; |
| }; |
| |
| vbiscreen_t * |
| vbiscreen_new (int video_width, int video_height, |
| double video_aspect, int verbose, void *user_data) |
| { |
| int i = 0, fontsize = FONT_SIZE; |
| vbiscreen_t *vs = (vbiscreen_t *) malloc (sizeof (struct vbiscreen_s)); |
| |
| if (!vs) { |
| return NULL; |
| } |
| |
| vs->verbose = verbose; |
| vs->x = 0; |
| vs->y = 0; |
| vs->frame_width = video_width; |
| vs->frame_height = video_height; |
| vs->frame_aspect = video_aspect; |
| vs->curx = 0; |
| vs->cury = 0; |
| vs->fgcolour = 0xFFFFFFFFU; /* white */ |
| vs->bgcolour = 0xFF000000U; /* black */ |
| vs->bg_luma = 16; |
| vs->bg_cb = 128; |
| vs->bg_cr = 128; |
| vs->rows = ROWS; |
| vs->cols = COLS; |
| /*vs->fontfile = DATADIR "/FreeMonoBold.ttf"; */ |
| vs->fontfile = NULL; |
| vs->fontsize = fontsize; |
| vs->width = video_width; |
| vs->height = video_height; |
| vs->first_line = 0; |
| vs->captions = 0; |
| vs->style = 0; |
| vs->curbuffer = 0; |
| vs->top_of_screen = 0; |
| vs->indent = 0; |
| memset (vs->buffers, 0, 2 * COLS * ROWS); |
| memset (vs->hiddenbuf, 0, COLS); |
| memset (vs->paintbuf, 0, ROWS * COLS); |
| vs->scroll = 0; |
| |
| vs->user_data = user_data; |
| |
| vs->line[0] = osd_string_new (vs->fontfile, fontsize, video_width, |
| video_height, video_aspect, user_data); |
| |
| if (!vs->line[0]) { |
| vs->fontfile = "./FreeMonoBold.ttf"; |
| |
| vs->line[0] = osd_string_new (vs->fontfile, fontsize, |
| video_width, video_height, video_aspect, user_data); |
| } |
| |
| if (!vs->line[0]) { |
| fprintf (stderr, "vbiscreen: Could not find my font (%s)!\n", vs->fontfile); |
| vbiscreen_delete (vs); |
| return NULL; |
| } |
| |
| osd_string_show_text (vs->line[0], "W", 0); |
| vs->rowheight = osd_string_get_height (vs->line[0]); |
| vs->charwidth = osd_string_get_width (vs->line[0]); |
| osd_string_delete (vs->line[0]); |
| |
| for (i = 0; i < ROWS; i++) { |
| vs->line[i] = osd_string_new (vs->fontfile, fontsize, |
| video_width, video_height, video_aspect, user_data); |
| if (!vs->line[i]) { |
| fprintf (stderr, "vbiscreen: Could not allocate a line.\n"); |
| vbiscreen_delete (vs); |
| return NULL; |
| } |
| osd_string_set_colour_rgb (vs->line[i], |
| (vs->fgcolour & 0xff0000) >> 16, |
| (vs->fgcolour & 0xff00) >> 8, (vs->fgcolour & 0xff)); |
| osd_string_show_text (vs->line[i], " ", 0); |
| } |
| memset (vs->text, 0, 2 * ROWS * COLS); |
| return vs; |
| } |
| |
| void |
| blank_screen (vbiscreen_t * vs) |
| { |
| int i; |
| |
| if (vs->verbose) |
| fprintf (stderr, "in blank\n"); |
| for (i = 0; i < ROWS; i++) { |
| osd_string_show_text (vs->line[i], " ", 0); |
| } |
| } |
| |
| void |
| clear_screen (vbiscreen_t * vs) |
| { |
| int base, i; |
| |
| if (!vs) |
| return; |
| |
| base = vs->top_of_screen * COLS; |
| for (i = 0; i < ROWS * COLS; i++) { |
| vs->text[base] = 0; |
| base++; |
| base %= 2 * ROWS * COLS; |
| } |
| blank_screen (vs); |
| } |
| |
| void |
| clear_hidden_roll (vbiscreen_t * vs) |
| { |
| if (!vs) |
| return; |
| memset (vs->hiddenbuf, 0, COLS); |
| } |
| |
| void |
| clear_hidden_pop (vbiscreen_t * vs) |
| { |
| if (!vs) |
| return; |
| memset (vs->buffers + vs->curbuffer * COLS * ROWS, 0, COLS * ROWS); |
| } |
| |
| void |
| clear_hidden_paint (vbiscreen_t * vs) |
| { |
| if (!vs) |
| return; |
| memset (vs->paintbuf, 0, COLS * ROWS); |
| } |
| |
| void |
| clear_displayed_pop (vbiscreen_t * vs) |
| { |
| if (!vs) |
| return; |
| memset (vs->buffers + (vs->curbuffer ^ 1) * COLS * ROWS, 0, COLS * ROWS); |
| } |
| |
| void |
| vbiscreen_dump_screen_text (vbiscreen_t * vs) |
| { |
| int i, offset; |
| |
| if (!vs) |
| return; |
| offset = vs->top_of_screen * COLS; |
| |
| fprintf (stderr, "\n 0123456789abcdefghij012345678901"); |
| for (i = 0; i < ROWS * COLS; i++) { |
| if (!(i % COLS)) |
| fprintf (stderr, "\n%.2d ", i / COLS); |
| fprintf (stderr, "%c", vs->text[offset] ? vs->text[offset] : ' '); |
| offset++; |
| offset %= 2 * ROWS * COLS; |
| } |
| fprintf (stderr, "\n 0123456789abcdefghij012345678901\n "); |
| for (i = 0; i < COLS; i++) { |
| fprintf (stderr, "%c", vs->text[offset] ? vs->text[offset] : ' '); |
| offset++; |
| offset %= 2 * ROWS * COLS; |
| } |
| fprintf (stderr, "\n 0123456789abcdefghij012345678901\n"); |
| } |
| |
| int |
| update_row_x (vbiscreen_t * vs, int row) |
| { |
| char text[COLS + 1]; |
| int i, j, haschars = 0, base; |
| |
| if (!vs) |
| return 0; |
| |
| text[COLS] = 0; |
| base = ((vs->top_of_screen + row) % (2 * ROWS)) * COLS; |
| for (j = 0, i = base; i < base + COLS; i++, j++) { |
| if (vs->text[i]) { |
| text[j] = vs->text[i]; |
| haschars = 1; |
| } else { |
| text[j] = ' '; |
| } |
| } |
| |
| osd_string_set_colour_rgb (vs->line[row], |
| (vs->fgcolour & 0xff0000) >> 16, |
| (vs->fgcolour & 0xff00) >> 8, (vs->fgcolour & 0xff)); |
| if (!haschars) |
| osd_string_show_text (vs->line[row], " ", 0); |
| else |
| osd_string_show_text (vs->line[row], text, 51); |
| |
| return haschars; |
| } |
| |
| void |
| update_row (vbiscreen_t * vs) |
| { |
| if (!vs) |
| return; |
| |
| update_row_x (vs, vs->cury); |
| //vbiscreen_dump_screen_text( vs ); |
| } |
| |
| void |
| update_all_rows (vbiscreen_t * vs) |
| { |
| int row = 0; |
| |
| if (!vs) |
| return; |
| |
| for (row = 0; row < ROWS; row++) { |
| update_row_x (vs, row); |
| } |
| //vbiscreen_dump_screen_text( vs ); |
| } |
| |
| void |
| vbiscreen_delete (vbiscreen_t * vs) |
| { |
| free (vs); |
| } |
| |
| void |
| copy_row_to_screen (vbiscreen_t * vs, char *row) |
| { |
| int base, i, j; |
| |
| base = ((vs->top_of_screen + vs->cury) % (2 * ROWS)) * COLS; |
| for (j = 0, i = base; i < base + COLS; j++, i++) { |
| vs->text[i] = row[j]; |
| } |
| update_row (vs); |
| } |
| |
| void |
| scroll_screen (vbiscreen_t * vs) |
| { |
| int start_row; |
| |
| if (!vs || !vs->captions || !vs->style || vs->style > ROLL_4) |
| return; |
| |
| start_row = (vs->first_line + vs->top_of_screen) % (2 * ROWS); |
| if (vs->verbose) |
| fprintf (stderr, "start row : %d first line %d\n ", start_row, |
| vs->first_line); |
| |
| /* zero out top row */ |
| memset ((char *) (vs->text + start_row * COLS), 0, COLS); |
| vs->top_of_screen = (vs->top_of_screen + 1) % (2 * ROWS); |
| vs->curx = vs->indent; |
| update_all_rows (vs); |
| copy_row_to_screen (vs, vs->hiddenbuf); |
| clear_hidden_roll (vs); |
| vs->scroll = 26; |
| } |
| |
| void |
| vbiscreen_set_verbose (vbiscreen_t * vs, int verbose) |
| { |
| vs->verbose = verbose; |
| } |
| |
| void |
| vbiscreen_new_caption (vbiscreen_t * vs, int indent, int ital, |
| unsigned int colour, int row) |
| { |
| if (!vs) |
| return; |
| if (vs->verbose) |
| fprintf (stderr, "indent: %d, ital: %d, colour: 0x%x, row: %d\n", indent, |
| ital, colour, row); |
| |
| if (0 && vs->captions && vs->style <= ROLL_4 && vs->style) { |
| if (row != vs->cury + 1) { |
| vs->cury = row - 1; |
| clear_hidden_roll (vs); |
| } else { |
| // scroll_screen( vs ); |
| } |
| } |
| |
| if (vs->style > ROLL_4) { |
| vs->cury = ((row > 0) ? row - 1 : 0); |
| } |
| |
| vs->fgcolour = colour; |
| vs->indent = indent; |
| vs->curx = indent; |
| } |
| |
| void |
| vbiscreen_set_mode (vbiscreen_t * vs, int caption, int style) |
| { |
| if (!vs) |
| return; |
| if (vs->verbose) |
| fprintf (stderr, "in set mode\n"); |
| |
| if (vs->verbose) { |
| fprintf (stderr, "Caption: %d ", caption); |
| switch (style) { |
| case ROLL_2: |
| fprintf (stderr, "ROLL 2\n"); |
| break; |
| case ROLL_3: |
| fprintf (stderr, "ROLL 3\n"); |
| break; |
| case ROLL_4: |
| fprintf (stderr, "ROLL 4\n"); |
| break; |
| case POP_UP: |
| fprintf (stderr, "POP UP\n"); |
| break; |
| case PAINT_ON: |
| fprintf (stderr, "PAINT ON\n"); |
| break; |
| default: |
| break; |
| } |
| } |
| if (!caption) { |
| /* text mode */ |
| vs->cury = 0; |
| } else { |
| /* captioning mode */ |
| /* styles: ru2 ru3 ru4 pop paint |
| */ |
| if (style != POP_UP && vs->style == POP_UP && !vs->got_eoc) { |
| /* stupid that sometimes they dont send a EOC */ |
| vbiscreen_end_of_caption (vs); |
| } |
| |
| switch (style) { |
| case ROLL_2: |
| case ROLL_3: |
| case ROLL_4: |
| if (vs->style == style) { |
| return; |
| } |
| vs->first_line = ROWS - (style - 4); |
| |
| if (vs->verbose) |
| fprintf (stderr, "first_line %d\n", vs->first_line); |
| |
| vs->cury = ROWS - 1; |
| break; |
| case POP_UP: |
| vs->got_eoc = 0; |
| break; |
| case PAINT_ON: |
| break; |
| } |
| } |
| |
| vs->captions = caption; |
| vs->style = style; |
| } |
| |
| void |
| vbiscreen_tab (vbiscreen_t * vs, int cols) |
| { |
| if (!vs) |
| return; |
| if (cols < 0 || cols > 3) |
| return; |
| vs->curx += cols; |
| if (vs->curx > 31) |
| vs->curx = 31; |
| } |
| |
| void |
| vbiscreen_set_colour (vbiscreen_t * vs, unsigned int col) |
| { |
| if (!vs) |
| return; |
| vs->fgcolour = col; |
| } |
| |
| void |
| vbiscreen_clear_current_cell (vbiscreen_t * vs) |
| { |
| vs->text[((vs->top_of_screen + vs->cury) % (2 * ROWS)) * COLS |
| + vs->curx + vs->indent] = 0; |
| } |
| |
| void |
| vbiscreen_set_current_cell (vbiscreen_t * vs, char text) |
| { |
| int base; |
| |
| if (!vs) |
| return; |
| base = ((vs->top_of_screen + vs->cury) % (2 * ROWS)) * COLS; |
| if (g_ascii_isprint (text)) |
| vs->text[base + vs->curx + vs->indent] = text; |
| else |
| vs->text[base + vs->curx + vs->indent] = ' '; |
| } |
| |
| void |
| vbiscreen_delete_to_end (vbiscreen_t * vs) |
| { |
| int i; |
| |
| if (!vs) |
| return; |
| if (vs->verbose) |
| fprintf (stderr, "in del to end\n"); |
| for (i = vs->curx; i < COLS; i++) { |
| vbiscreen_clear_current_cell (vs); |
| vs->curx++; |
| } |
| vs->curx = COLS - 1; /* is this right ? */ |
| if (vs->captions && vs->style && vs->style != POP_UP) |
| update_row (vs); |
| } |
| |
| void |
| vbiscreen_backspace (vbiscreen_t * vs) |
| { |
| if (!vs) |
| return; |
| if (vs->verbose) |
| fprintf (stderr, "in backspace\n"); |
| if (!vs->curx) |
| return; |
| vs->curx--; |
| vbiscreen_clear_current_cell (vs); |
| update_row (vs); |
| } |
| |
| void |
| vbiscreen_erase_displayed (vbiscreen_t * vs) |
| { |
| if (!vs) |
| return; |
| if (vs->verbose) |
| fprintf (stderr, "in erase disp\n"); |
| |
| if (vs->captions && vs->style && vs->style <= ROLL_4) { |
| clear_hidden_roll (vs); |
| } |
| |
| clear_displayed_pop (vs); |
| clear_screen (vs); |
| } |
| |
| void |
| vbiscreen_erase_non_displayed (vbiscreen_t * vs) |
| { |
| if (!vs) |
| return; |
| if (vs->verbose) |
| fprintf (stderr, "in erase non disp\n"); |
| |
| if (vs->captions && vs->style == POP_UP) { |
| memset (vs->buffers + vs->curbuffer * COLS * ROWS + vs->cury * COLS, 0, |
| COLS); |
| // clear_hidden_pop( vs ); |
| } else if (vs->captions && vs->style && vs->style <= ROLL_4) { |
| clear_hidden_roll (vs); |
| } |
| } |
| |
| void |
| vbiscreen_carriage_return (vbiscreen_t * vs) |
| { |
| if (!vs) |
| return; |
| if (vs->verbose) |
| fprintf (stderr, "in CR\n"); |
| if (vs->style != POP_UP) { |
| /* not sure if this is right for text mode */ |
| /* in text mode, perhaps a CR on last row clears screen and goes |
| * to (0,0) */ |
| scroll_screen (vs); |
| } |
| |
| /* keep cursor on bottom for rollup */ |
| if (vs->captions && vs->style && vs->style <= ROLL_4) |
| vs->cury--; |
| |
| vs->cury++; |
| vs->curx = 0; |
| } |
| |
| void |
| copy_buf_to_screen (vbiscreen_t * vs, char *buf) |
| { |
| int base, i, j; |
| |
| if (!vs) |
| return; |
| |
| base = vs->top_of_screen * COLS; |
| for (j = 0, i = 0; i < ROWS * COLS; i++, j++) { |
| vs->text[base] = buf[j]; |
| base++; |
| base %= 2 * ROWS * COLS; |
| } |
| update_all_rows (vs); |
| } |
| |
| void |
| vbiscreen_end_of_caption (vbiscreen_t * vs) |
| { |
| /*int i; */ |
| if (!vs) |
| return; |
| if (vs->verbose) |
| fprintf (stderr, "in end of caption\n"); |
| |
| if (vs->style == PAINT_ON) { |
| copy_buf_to_screen (vs, vs->paintbuf); |
| clear_hidden_paint (vs); |
| } else if (vs->style == POP_UP) { |
| copy_buf_to_screen (vs, vs->buffers + vs->curbuffer * COLS * ROWS); |
| vs->curbuffer ^= 1; |
| } |
| |
| /* to be safe? */ |
| vs->curx = 0; |
| vs->cury = ROWS - 1; |
| vs->got_eoc = 1; |
| } |
| |
| void |
| vbiscreen_print (vbiscreen_t * vs, char c1, char c2) |
| { |
| if (!vs) |
| return; |
| if (vs->verbose) |
| fprintf (stderr, "in print (%d, %d)[%c %c]\n", vs->curx, vs->cury, c1, c2); |
| if (vs->captions && vs->style == POP_UP) { |
| /* this all gets displayed at another time */ |
| if (vs->curx != COLS - 1) { |
| *(vs->buffers + vs->curx + vs->curbuffer * ROWS * COLS + |
| vs->cury * COLS) = c1; |
| vs->curx++; |
| } |
| |
| if (vs->curx != COLS - 1 && c2) { |
| *(vs->buffers + vs->curx + vs->curbuffer * ROWS * COLS + |
| vs->cury * COLS) = c2; |
| vs->curx++; |
| } else if (c2) { |
| *(vs->buffers + vs->curx + vs->curbuffer * ROWS * COLS + |
| vs->cury * COLS) = c2; |
| } |
| } |
| |
| if (vs->captions && vs->style == PAINT_ON) { |
| if (vs->curx != COLS - 1) { |
| vs->paintbuf[vs->curx + vs->cury * COLS] = c1; |
| vs->curx++; |
| } |
| |
| if (vs->curx != COLS - 1 && c2) { |
| vs->paintbuf[vs->curx + vs->cury * COLS] = c2; |
| vs->curx++; |
| } else if (c2) { |
| vs->paintbuf[vs->curx + vs->cury * COLS] = c2; |
| } |
| } |
| |
| if (vs->captions && vs->style && vs->style <= ROLL_4) { |
| if (vs->curx != COLS - 1) { |
| vs->hiddenbuf[vs->curx] = c1; |
| vs->curx++; |
| } else { |
| vs->hiddenbuf[vs->curx] = c1; |
| } |
| |
| if (vs->curx != COLS - 1 && c2) { |
| vs->hiddenbuf[vs->curx] = c2; |
| vs->curx++; |
| } else if (c2) { |
| vs->hiddenbuf[vs->curx] = c2; |
| } |
| } |
| } |
| |
| void |
| vbiscreen_reset (vbiscreen_t * vs) |
| { |
| if (!vs) |
| return; |
| clear_screen (vs); |
| clear_hidden_pop (vs); |
| clear_displayed_pop (vs); |
| clear_hidden_roll (vs); |
| vs->captions = 0; |
| vs->style = 0; |
| } |
| |
| void |
| vbiscreen_composite_packed422_scanline (vbiscreen_t * vs, |
| unsigned char *output, int width, int xpos, int scanline) |
| { |
| int x = 0, y = 0, row = 0, index = 0; |
| |
| if (!vs) |
| return; |
| if (!output) |
| return; |
| if (scanline >= vs->y && scanline < vs->y + vs->height) { |
| |
| if (0 && !vs->captions) |
| blit_colour_packed422_scanline (output + (vs->x * 2), vs->width, |
| vs->bg_luma, vs->bg_cb, vs->bg_cr); |
| |
| index = vs->top_of_screen * COLS; |
| x = (vs->x + vs->charwidth) & ~1; |
| for (row = 0; row < ROWS; row++) { |
| y = vs->y + row * vs->rowheight + vs->rowheight; |
| if (osd_string_visible (vs->line[row])) { |
| if (scanline >= y && scanline < y + vs->rowheight) { |
| |
| int startx; |
| int strx; |
| |
| startx = x - xpos; |
| strx = 0; |
| |
| if (startx < 0) { |
| strx = -startx; |
| startx = 0; |
| } |
| |
| |
| if (startx < width) { |
| |
| if (vs->captions) |
| blit_colour_packed422_scanline (output + (startx * 2), |
| osd_string_get_width (vs->line[row]), |
| vs->bg_luma, vs->bg_cb, vs->bg_cr); |
| |
| osd_string_composite_packed422_scanline (vs->line[row], |
| output + (startx * 2), |
| output + (startx * 2), width - startx, strx, scanline - y); |
| } |
| } |
| index++; |
| } |
| } |
| } |
| } |