mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-24 02:31:03 +00:00
initial checkin of work-in-progress vbidec plugin for closed caption support
Original commit message from CVS: initial checkin of work-in-progress vbidec plugin for closed caption support
This commit is contained in:
parent
08d0c89de5
commit
61898506c8
8 changed files with 2321 additions and 1 deletions
|
@ -233,7 +233,7 @@ GST_PLUGINS_ALL="\
|
|||
mpegaudio mpegaudioparse mpegstream mpegtypes\
|
||||
monoscope passthrough playondemand qtdemux rtjpeg silence sine\
|
||||
smooth smpte spectrum speed stereo stereomono synaesthesia\
|
||||
udp videocrop videoscale videotestsrc volenv volume\
|
||||
udp vbidec videocrop videoscale videotestsrc volenv volume\
|
||||
vumeter wavenc wavparse y4m"
|
||||
|
||||
dnl see if we can build C++ plug-ins
|
||||
|
@ -1014,6 +1014,7 @@ gst/stereo/Makefile
|
|||
gst/stereomono/Makefile
|
||||
gst/synaesthesia/Makefile
|
||||
gst/udp/Makefile
|
||||
gst/vbidec/Makefile
|
||||
gst/videoscale/Makefile
|
||||
gst/videotestsrc/Makefile
|
||||
gst/videocrop/Makefile
|
||||
|
|
9
gst/vbidec/Makefile.am
Normal file
9
gst/vbidec/Makefile.am
Normal file
|
@ -0,0 +1,9 @@
|
|||
plugindir = $(libdir)/gstreamer-@GST_MAJORMINOR@
|
||||
|
||||
plugin_LTLIBRARIES = libgstvbidec.la
|
||||
|
||||
libgstvbidec_la_SOURCES = gstvbidec.h gstvbidec.c \
|
||||
vbidata.h vbidata.c \
|
||||
vbiscreen.h vbiscreen.c
|
||||
libgstvbidec_la_CFLAGS = $(GST_CFLAGS)
|
||||
libgstvbidec_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
372
gst/vbidec/gstvbidec.c
Normal file
372
gst/vbidec/gstvbidec.c
Normal file
|
@ -0,0 +1,372 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <ctype.h>
|
||||
#include <gst/gst.h>
|
||||
#include "gstvbidec.h"
|
||||
#include "vbidata.h"
|
||||
#include "vbiscreen.h"
|
||||
|
||||
#define GST_TYPE_VBIDEC \
|
||||
(gst_vbidec_get_type())
|
||||
#define GST_VBIDEC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VBIDEC,GstVBIDec))
|
||||
#define GST_VBIDEC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VBIDEC,GstVBIDec))
|
||||
#define GST_IS_VBIDEC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VBIDEC))
|
||||
#define GST_IS_VBIDEC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VBIDEC))
|
||||
|
||||
//typedef struct _GstVBIDec GstVBIDec;
|
||||
typedef struct _GstVBIDecClass GstVBIDecClass;
|
||||
|
||||
struct _GstVBIDec {
|
||||
GstElement element;
|
||||
|
||||
/* pads */
|
||||
GstPad *sinkpad,
|
||||
*srcpad;
|
||||
char caption[128];
|
||||
vbiscreen_t *vbiscreen;
|
||||
vbidata_t *vbidata;
|
||||
int caption_type;
|
||||
gboolean dvd_input;
|
||||
};
|
||||
|
||||
struct _GstVBIDecClass {
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
|
||||
GType gst_vbidec_get_type(void);
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_vbidec_details = {
|
||||
"VBI decoder",
|
||||
"Codec/Video/Decoder",
|
||||
"GPL",
|
||||
"Decodes closed captions and XDS data from VBI data",
|
||||
VERSION,
|
||||
"David I. Lehn <dlehn@users.sourceforge.net>",
|
||||
"(C) 2002"
|
||||
};
|
||||
|
||||
/* VBIDec signals and args */
|
||||
enum {
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum {
|
||||
ARG_0,
|
||||
ARG_CAPTION_TYPE,
|
||||
ARG_DVD_INPUT
|
||||
};
|
||||
|
||||
GST_PAD_TEMPLATE_FACTORY (sink_template_factory,
|
||||
"sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_CAPS_NEW (
|
||||
"vbidec_sink",
|
||||
"application/octet-stream",
|
||||
NULL
|
||||
)
|
||||
);
|
||||
|
||||
GST_PAD_TEMPLATE_FACTORY (src_template_factory,
|
||||
"src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_CAPS_NEW (
|
||||
"vbidec_src",
|
||||
"text/plain",
|
||||
NULL
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
#define GST_TYPE_VBIDEC_CAPTION_TYPE_TYPE (gst_vbidec_caption_type_get_type())
|
||||
static GType
|
||||
gst_vbidec_caption_type_get_type (void)
|
||||
{
|
||||
static GType vbidec_caption_type_type = 0;
|
||||
static GEnumValue vbidec_caption_type[] = {
|
||||
{ CAPTURE_OFF, "0", "Closed Captions off"},
|
||||
{ CAPTURE_CC1, "1", "Closed Caption CC1"},
|
||||
{ CAPTURE_CC2, "2", "Closed Caption CC2"},
|
||||
{ CAPTURE_CC3, "4", "Closed Caption CC3"},
|
||||
{ CAPTURE_CC4, "5", "Closed Caption CC4"},
|
||||
{ CAPTURE_T1, "6", "Closed Caption T1"},
|
||||
{ CAPTURE_T2, "7", "Closed Caption T2"},
|
||||
{ CAPTURE_T3, "8", "Closed Caption T3"},
|
||||
{ CAPTURE_T4, "9", "Closed Caption T4"},
|
||||
{0, NULL, NULL},
|
||||
};
|
||||
if (!vbidec_caption_type_type) {
|
||||
vbidec_caption_type_type = g_enum_register_static ("GstVBIDecCaptionTypeType", vbidec_caption_type);
|
||||
}
|
||||
return vbidec_caption_type_type;
|
||||
}
|
||||
|
||||
static void gst_vbidec_class_init (GstVBIDecClass *klass);
|
||||
static void gst_vbidec_init (GstVBIDec *vbidec);
|
||||
|
||||
static void gst_vbidec_set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec);
|
||||
static void gst_vbidec_get_property (GObject *object, guint prop_id,
|
||||
GValue *value, GParamSpec *pspec);
|
||||
|
||||
static void gst_vbidec_chain (GstPad *pad, GstBuffer *buffer);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
/*static guint gst_vbidec_signals[LAST_SIGNAL] = { 0 };*/
|
||||
|
||||
GType
|
||||
gst_vbidec_get_type (void)
|
||||
{
|
||||
static GType vbidec_type = 0;
|
||||
|
||||
if (!vbidec_type) {
|
||||
static const GTypeInfo vbidec_info = {
|
||||
sizeof(GstVBIDecClass),
|
||||
NULL,
|
||||
NULL,
|
||||
(GClassInitFunc)gst_vbidec_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof(GstVBIDec),
|
||||
0,
|
||||
(GInstanceInitFunc)gst_vbidec_init,
|
||||
};
|
||||
vbidec_type = g_type_register_static(GST_TYPE_ELEMENT, "GstVBIDec", &vbidec_info, 0);
|
||||
}
|
||||
return vbidec_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vbidec_class_init(GstVBIDecClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
||||
gobject_class = (GObjectClass*)klass;
|
||||
gstelement_class = (GstElementClass*)klass;
|
||||
|
||||
parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
|
||||
|
||||
gobject_class->set_property = gst_vbidec_set_property;
|
||||
gobject_class->get_property = gst_vbidec_get_property;
|
||||
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_CAPTION_TYPE,
|
||||
g_param_spec_enum ("caption type", "caption type", "Closed Caption Type",
|
||||
GST_TYPE_VBIDEC_CAPTION_TYPE_TYPE, CAPTURE_OFF, G_PARAM_READWRITE));
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DVD_INPUT,
|
||||
g_param_spec_boolean ("dvd input", "dvd input", "VBI is encapsulated in MPEG2 GOP user_data field (as on DVDs)",
|
||||
FALSE, G_PARAM_READWRITE));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vbidec_init (GstVBIDec *vbidec)
|
||||
{
|
||||
/* create the sink and src pads */
|
||||
vbidec->sinkpad = gst_pad_new_from_template (
|
||||
GST_PAD_TEMPLATE_GET (sink_template_factory), "sink");
|
||||
gst_element_add_pad (GST_ELEMENT (vbidec), vbidec->sinkpad);
|
||||
gst_pad_set_chain_function (vbidec->sinkpad, GST_DEBUG_FUNCPTR (gst_vbidec_chain));
|
||||
|
||||
vbidec->srcpad = gst_pad_new_from_template (
|
||||
GST_PAD_TEMPLATE_GET (src_template_factory), "src");
|
||||
gst_element_add_pad (GST_ELEMENT (vbidec), vbidec->srcpad);
|
||||
|
||||
vbidec->vbiscreen = vbiscreen_new(0, 0, 1.0, 0, (void *)vbidec);
|
||||
vbidec->vbidata = vbidata_new_line(vbidec->vbiscreen, 0);
|
||||
vbidec->caption_type = CAPTURE_OFF;
|
||||
vbidata_capture_mode(vbidec->vbidata, vbidec->caption_type);
|
||||
vbidec->dvd_input = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
line21_decode(GstVBIDec *vbidec, guint8 *data, guint32 size)
|
||||
{
|
||||
vbidata_process_line(vbidec->vbidata, data, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
dvd_user_data_decode(GstVBIDec *vbidec, guint8 *data, guint32 size)
|
||||
{
|
||||
//char caption[128];
|
||||
//int ci; /* caption index */
|
||||
int i; /* buf index */
|
||||
int num_disp_field;
|
||||
guint8 b1, b2;
|
||||
int w;
|
||||
|
||||
//g_print("%%%% vbi decode\n");
|
||||
//g_print("== %p %d\n", data, size);
|
||||
i = 0;
|
||||
/* Check for Closed Captioning data */
|
||||
if (data[i] != 0x43 || data[i+1] != 0x43 ||
|
||||
data[i+2] != 0x01 || data[i+3] != 0xf8) {
|
||||
g_print ("non-CC data\n");
|
||||
return;
|
||||
}
|
||||
//g_print ("CC data\n");
|
||||
i += 4; /* above */
|
||||
i += 4; /* ? */
|
||||
num_disp_field = data[i] & 0x3f;
|
||||
//g_print ("ndf %d\n", num_disp_field);
|
||||
while ((data[i] & 0xfe) == 0xfe) {
|
||||
if (data[i] & 0x1) {
|
||||
b1 = data[i+1] & 0x7f;
|
||||
b2 = data[i+2] & 0x7f;
|
||||
w = (b2 << 8) | b1;
|
||||
vbidata_process_16b(vbidec->vbidata, 0, w);
|
||||
}
|
||||
i += 3;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vbidec_chain (GstPad *pad, GstBuffer *buf)
|
||||
{
|
||||
GstVBIDec *vbidec = GST_VBIDEC (gst_pad_get_parent (pad));
|
||||
guint32 size;
|
||||
guint8 *data;
|
||||
guint64 pts;
|
||||
|
||||
size = GST_BUFFER_SIZE (buf);
|
||||
data = GST_BUFFER_DATA (buf);
|
||||
pts = GST_BUFFER_TIMESTAMP (buf);
|
||||
|
||||
/*
|
||||
g_print("** user_data: addr:%p len:%d state:%d\n", data, size, 0);
|
||||
{
|
||||
int i;
|
||||
guint8 ud;
|
||||
g_print("** \"");
|
||||
for (i=0; i<size; i++) {
|
||||
ud = data[i];
|
||||
if (isprint((char)ud)) {
|
||||
g_print("%c", (char)ud);
|
||||
} else {
|
||||
g_print("[0x%02x]", ud);
|
||||
}
|
||||
}
|
||||
g_print("\"\n");
|
||||
}
|
||||
*/
|
||||
|
||||
if (vbidec->dvd_input) {
|
||||
dvd_user_data_decode(vbidec, data, size);
|
||||
} else {
|
||||
line21_decode(vbidec, data, size);
|
||||
}
|
||||
|
||||
gst_buffer_unref(buf);
|
||||
}
|
||||
|
||||
void
|
||||
gst_vbidec_show_text (GstVBIDec *vbidec, char *text, int len)
|
||||
{
|
||||
//fprintf(stderr, "%*s\n", len, text);
|
||||
if (len > 0) {
|
||||
if (GST_PAD_IS_USABLE (vbidec->srcpad)) {
|
||||
GstBuffer *buf = gst_buffer_new_and_alloc (len);
|
||||
memcpy (GST_BUFFER_DATA (buf), text, len);
|
||||
GST_BUFFER_SIZE (buf) = len;
|
||||
// FIXME
|
||||
//GST_BUFFER_TIMESTAMP (buf) = vbidec->...
|
||||
//...
|
||||
//fprintf(stderr, "vbi text pushed\n");
|
||||
gst_pad_push (vbidec->srcpad, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vbidec_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
GstVBIDec *vbidec;
|
||||
|
||||
/* it's not null if we got it, but it might not be ours */
|
||||
g_return_if_fail (GST_IS_VBIDEC (object));
|
||||
vbidec = GST_VBIDEC (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case ARG_DVD_INPUT:
|
||||
vbidec->dvd_input = g_value_get_boolean(value);
|
||||
break;
|
||||
case ARG_CAPTION_TYPE:
|
||||
vbidec->caption_type = g_value_get_enum(value);
|
||||
vbidata_capture_mode(vbidec->vbidata, vbidec->caption_type);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vbidec_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
GstVBIDec *vbidec;
|
||||
|
||||
/* it's not null if we got it, but it might not be ours */
|
||||
g_return_if_fail (GST_IS_VBIDEC (object));
|
||||
vbidec = GST_VBIDEC (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case ARG_DVD_INPUT:
|
||||
g_value_set_boolean(value, vbidec->dvd_input);
|
||||
break;
|
||||
case ARG_CAPTION_TYPE:
|
||||
g_value_set_enum(value, vbidec->caption_type);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
plugin_init (GModule *module, GstPlugin *plugin)
|
||||
{
|
||||
GstElementFactory *factory;
|
||||
|
||||
/* create an elementfactory for the vbidec element */
|
||||
factory = gst_element_factory_new("vbidec",GST_TYPE_VBIDEC,
|
||||
&gst_vbidec_details);
|
||||
g_return_val_if_fail(factory != NULL, FALSE);
|
||||
gst_element_factory_set_rank (factory, GST_ELEMENT_RANK_PRIMARY);
|
||||
|
||||
gst_element_factory_add_pad_template (factory, GST_PAD_TEMPLATE_GET (src_template_factory));
|
||||
gst_element_factory_add_pad_template (factory, GST_PAD_TEMPLATE_GET (sink_template_factory));
|
||||
|
||||
gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GstPluginDesc plugin_desc = {
|
||||
GST_VERSION_MAJOR,
|
||||
GST_VERSION_MINOR,
|
||||
"vbidec",
|
||||
plugin_init
|
||||
};
|
22
gst/vbidec/gstvbidec.h
Normal file
22
gst/vbidec/gstvbidec.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
typedef struct _GstVBIDec GstVBIDec;
|
||||
|
||||
void gst_vbidec_show_text (GstVBIDec *vbidec, char *text, int len);
|
1079
gst/vbidec/vbidata.c
Normal file
1079
gst/vbidec/vbidata.c
Normal file
File diff suppressed because it is too large
Load diff
58
gst/vbidec/vbidata.h
Normal file
58
gst/vbidec/vbidata.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* Copyright (c) 2002 Billy Biggs <vektor@dumbterm.net>.
|
||||
* Copyright (c) 2002 Doug Bell <drbell@users.sourceforge.net>
|
||||
*
|
||||
* CC code from Nathan Laredo's ccdecode.
|
||||
* Lots of 'hey what does this mean?' code from
|
||||
* Billy Biggs and Doug Bell, like all the crap with
|
||||
* XDS and stuff. Some help from Zapping's vbi library by
|
||||
* Michael H. Schimek and others, released under the GPL.
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef VBIDATA_H_INCLUDED
|
||||
#define VBIDATA_H_INCLUDED
|
||||
|
||||
#include "vbiscreen.h"
|
||||
/*#include "tvtimeosd.h"*/
|
||||
|
||||
typedef struct vbidata_s vbidata_t;
|
||||
|
||||
#define CAPTURE_OFF 0
|
||||
#define CAPTURE_CC1 1
|
||||
#define CAPTURE_CC2 2
|
||||
#define CAPTURE_CC3 4
|
||||
#define CAPTURE_CC4 5
|
||||
#define CAPTURE_T1 6
|
||||
#define CAPTURE_T2 7
|
||||
#define CAPTURE_T3 8
|
||||
#define CAPTURE_T4 9
|
||||
|
||||
vbidata_t *vbidata_new_file( const char *filename, vbiscreen_t *vs,
|
||||
/*tvtime_osd_t* osd,*/ int verbose );
|
||||
vbidata_t *vbidata_new_line( vbiscreen_t *vs, int verbose );
|
||||
|
||||
void vbidata_delete( vbidata_t *vbi );
|
||||
void vbidata_reset( vbidata_t *vbi );
|
||||
void vbidata_capture_mode( vbidata_t *vbi, int mode );
|
||||
void vbidata_process_frame( vbidata_t *vbi, int printdebug );
|
||||
void vbidata_process_line( vbidata_t *vbi, unsigned char *s, int bottom );
|
||||
void vbidata_process_16b( vbidata_t *vbi, int bottom, int w );
|
||||
|
||||
#endif /* VBIDATA_H_INCLUDED */
|
730
gst/vbidec/vbiscreen.c
Normal file
730
gst/vbidec/vbiscreen.c
Normal file
|
@ -0,0 +1,730 @@
|
|||
/**
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#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 "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_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( 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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
49
gst/vbidec/vbiscreen.h
Normal file
49
gst/vbidec/vbiscreen.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef HAVE_VBISCREEN_H
|
||||
#define HAVE_VBISCREEN_H
|
||||
|
||||
typedef struct vbiscreen_s vbiscreen_t;
|
||||
|
||||
vbiscreen_t *vbiscreen_new( int video_width, int video_height,
|
||||
double video_aspect, int verbose, void *user_data );
|
||||
void vbiscreen_delete( vbiscreen_t *vs );
|
||||
void vbiscreen_set_mode( vbiscreen_t *vs, int caption, int style);
|
||||
void vbiscreen_new_caption( vbiscreen_t *vs, int indent, int ital,
|
||||
unsigned int colour, int row );
|
||||
void vbiscreen_tab( vbiscreen_t *vs, int cols );
|
||||
void vbiscreen_delete_to_end( vbiscreen_t *vs );
|
||||
void vbiscreen_backspace( vbiscreen_t *vs );
|
||||
void vbiscreen_erase_displayed( vbiscreen_t *vs );
|
||||
void vbiscreen_erase_non_displayed( vbiscreen_t *vs );
|
||||
void vbiscreen_carriage_return( vbiscreen_t *vs );
|
||||
void vbiscreen_end_of_caption( vbiscreen_t *vs );
|
||||
void vbiscreen_print( vbiscreen_t *vs, char c1, char c2 );
|
||||
void vbiscreen_composite_packed422_scanline( vbiscreen_t *vs,
|
||||
unsigned char *output,
|
||||
int width, int xpos,
|
||||
int scanline );
|
||||
void vbiscreen_dump_screen_text( vbiscreen_t *vs );
|
||||
void vbiscreen_reset( vbiscreen_t *vs );
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue