mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11:08 +00:00
ceaccoverlay: New CEA-708 Closed Caption decoder and overlayer
This new element allows decoding and overlaying CEA-708 Closed Caption streams over video. * Supports CDP and cc_data closedcaption/x-cea-708 streams * Uses pango to render CC stream * Support GstVideoOverlayComposition meta if downstream supports is Tested on various test files. Remains to be fixed/improved: * Switch to GstByteReader (for code safety) * Switch to GString (instead of manual pango string construction) * Move pango/rendering code outside of main 708 decoder file (so that actual CC parser/decoder can be (re)used in other scenarios). Initial patches and improvements by: * CableLabs RUIH-RI Team <ruihri@cablelabs.com> * Steve Maynard <steve@secondstryke.com> * cjun.wang" <cjun.wang@samsung.com> https://bugzilla.gnome.org/show_bug.cgi?id=704881
This commit is contained in:
parent
aab111b979
commit
a41fb3c6df
7 changed files with 4386 additions and 6 deletions
|
@ -21,6 +21,10 @@ libgstclosedcaption_la_SOURCES = \
|
||||||
$(zvbi_headers) \
|
$(zvbi_headers) \
|
||||||
gstccextractor.c \
|
gstccextractor.c \
|
||||||
gstccextractor.h \
|
gstccextractor.h \
|
||||||
|
gstcea708decoder.c \
|
||||||
|
gstcea708decoder.h \
|
||||||
|
gstceaccoverlay.c \
|
||||||
|
gstceaccoverlay.h \
|
||||||
gstline21dec.c \
|
gstline21dec.c \
|
||||||
gstline21dec.h \
|
gstline21dec.h \
|
||||||
gstclosedcaption.c
|
gstclosedcaption.c
|
||||||
|
@ -28,12 +32,14 @@ libgstclosedcaption_la_SOURCES = \
|
||||||
libgstclosedcaption_la_CFLAGS = \
|
libgstclosedcaption_la_CFLAGS = \
|
||||||
$(GST_PLUGINS_BASE_CFLAGS) \
|
$(GST_PLUGINS_BASE_CFLAGS) \
|
||||||
$(GST_BASE_CFLAGS) \
|
$(GST_BASE_CFLAGS) \
|
||||||
$(GST_CFLAGS)
|
$(GST_CFLAGS) \
|
||||||
|
$(PANGO_CFLAGS)
|
||||||
|
|
||||||
libgstclosedcaption_la_LIBADD = \
|
libgstclosedcaption_la_LIBADD = \
|
||||||
$(GST_PLUGINS_BASE_LIBS) -lgstvideo-@GST_API_VERSION@ \
|
$(GST_PLUGINS_BASE_LIBS) -lgstvideo-@GST_API_VERSION@ \
|
||||||
$(GST_BASE_LIBS) \
|
$(GST_BASE_LIBS) \
|
||||||
$(GST_LIBS)
|
$(GST_LIBS) \
|
||||||
|
$(PANGO_LIBS)
|
||||||
|
|
||||||
libgstclosedcaption_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
libgstclosedcaption_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||||
|
|
||||||
|
|
1791
ext/closedcaption/gstcea708decoder.c
Normal file
1791
ext/closedcaption/gstcea708decoder.c
Normal file
File diff suppressed because it is too large
Load diff
485
ext/closedcaption/gstcea708decoder.h
Normal file
485
ext/closedcaption/gstcea708decoder.h
Normal file
|
@ -0,0 +1,485 @@
|
||||||
|
/* GStreamer
|
||||||
|
* Copyright (C) 2013 CableLabs, Louisville, CO 80027
|
||||||
|
* Copyright (C) 2015 Samsung Electronics Co., Ltd.
|
||||||
|
* @Author: Chengjun Wang <cjun.wang@samsung.com>
|
||||||
|
*
|
||||||
|
* 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., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __GST_CEA708_DEC_H__
|
||||||
|
#define __GST_CEA708_DEC_H__
|
||||||
|
|
||||||
|
#include <gst/gst.h>
|
||||||
|
#include <pango/pangocairo.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
/* from ATSC A/53 Part 4
|
||||||
|
* DTVCC packets are 128 bytes MAX, length is only 6 bits, header is 2 bytes,
|
||||||
|
* the last byte is flag-fill, that leaves 125 possible bytes of data to be
|
||||||
|
* represented in 6 bits, hence the length encoding
|
||||||
|
*/
|
||||||
|
/* should never be more than 128 */
|
||||||
|
#define DTVCC_LENGTH 128
|
||||||
|
#define DTVCC_PKT_SIZE(sz_byte) (((sz_byte) == 0) ? 127 : ((sz_byte) * 2) -1)
|
||||||
|
#define CCTYPE_VALID_MASK 0x04
|
||||||
|
#define CCTYPE_TYPE_MASK 0x03
|
||||||
|
#define NUM_608_CCTYPES 2
|
||||||
|
/* CEA-708-B commands */
|
||||||
|
/* EndOfText */
|
||||||
|
#define CC_COMMAND_ETX 0x03
|
||||||
|
/* SetCurrentWindow0 */
|
||||||
|
#define CC_COMMAND_CW0 0x80
|
||||||
|
#define CC_COMMAND_CW1 0x81
|
||||||
|
#define CC_COMMAND_CW2 0x82
|
||||||
|
#define CC_COMMAND_CW3 0x83
|
||||||
|
#define CC_COMMAND_CW4 0x84
|
||||||
|
#define CC_COMMAND_CW5 0x85
|
||||||
|
#define CC_COMMAND_CW6 0x86
|
||||||
|
#define CC_COMMAND_CW7 0x87
|
||||||
|
/* ClearWindows */
|
||||||
|
#define CC_COMMAND_CLW 0x88
|
||||||
|
/* DisplayWindows */
|
||||||
|
#define CC_COMMAND_DSW 0x89
|
||||||
|
/* HideWindows */
|
||||||
|
#define CC_COMMAND_HDW 0x8A
|
||||||
|
/* ToggleWindows */
|
||||||
|
#define CC_COMMAND_TGW 0x8B
|
||||||
|
/* DeleteWindows */
|
||||||
|
#define CC_COMMAND_DLW 0x8C
|
||||||
|
/* Delay */
|
||||||
|
#define CC_COMMAND_DLY 0x8D
|
||||||
|
/* DelayCancel */
|
||||||
|
#define CC_COMMAND_DLC 0x8E
|
||||||
|
/* Reset */
|
||||||
|
#define CC_COMMAND_RST 0x8F
|
||||||
|
/* SetPenAttributes */
|
||||||
|
#define CC_COMMAND_SPA 0x90
|
||||||
|
/* SetPenColor */
|
||||||
|
#define CC_COMMAND_SPC 0x91
|
||||||
|
/* SetPenLocation */
|
||||||
|
#define CC_COMMAND_SPL 0x92
|
||||||
|
/* SetWindowAttributes */
|
||||||
|
#define CC_COMMAND_SWA 0x97
|
||||||
|
/* DefineWindow0 */
|
||||||
|
#define CC_COMMAND_DF0 0x98
|
||||||
|
#define CC_COMMAND_DF1 0x99
|
||||||
|
#define CC_COMMAND_DF2 0x9A
|
||||||
|
#define CC_COMMAND_DF3 0x9B
|
||||||
|
#define CC_COMMAND_DF4 0x9C
|
||||||
|
#define CC_COMMAND_DF5 0x9D
|
||||||
|
#define CC_COMMAND_DF6 0x9E
|
||||||
|
#define CC_COMMAND_DF7 0x9F
|
||||||
|
/* music note unicode */
|
||||||
|
#define CC_SPECIAL_CODE_MUSIC_NOTE 0x266a
|
||||||
|
#define CC_UTF8_MAX_LENGTH 6
|
||||||
|
#define CC_MAX_CODE_SET_SIZE 96
|
||||||
|
/* Per CEA-708 spec there may be 8 CC windows */
|
||||||
|
#define MAX_708_WINDOWS 8
|
||||||
|
/* Each 708 window contains a grid of character positions. These are the
|
||||||
|
* max limits defined, but each window has a row/col count which is typically
|
||||||
|
* smaller than the limits. Note this is just one window, not the entire screen.
|
||||||
|
*/
|
||||||
|
/* max row count */
|
||||||
|
#define WINDOW_MAX_ROWS 15
|
||||||
|
/* max column width */
|
||||||
|
#define WINDOW_MAX_COLS 42
|
||||||
|
/* The linebuffer contains text for 1 line pango text corresponding to 1 line of 708 text.
|
||||||
|
* The linebuffer could be a lot larger than the window text because of required markup.
|
||||||
|
* example <u> </u> for underline.
|
||||||
|
* The size given is an estimate, to be changed if determined that a larger
|
||||||
|
* buffer is needed
|
||||||
|
*/
|
||||||
|
#define LINEBUFFER_SIZE 1024
|
||||||
|
/* The screen width/height defined by 708 - not character units, these are
|
||||||
|
* used only to determine the position of the anchor on the screen.
|
||||||
|
*/
|
||||||
|
#define SCREEN_WIDTH_16_9 209
|
||||||
|
#define SCREEN_HEIGHT_16_9 74
|
||||||
|
#define SCREEN_WIDTH_4_3 159
|
||||||
|
#define SCREEN_HEIGHT_4_3 74
|
||||||
|
|
||||||
|
/* raw bytes of "define window" command */
|
||||||
|
#define WIN_DEF_SIZE 6
|
||||||
|
/* The maximum size of a 708 window in character units. This is used to
|
||||||
|
* calculate the position of windows based on window anchor positions.
|
||||||
|
*/
|
||||||
|
#define SCREEN_HEIGHT_708 15
|
||||||
|
#define SCREEN_WIDTH_708 32
|
||||||
|
/* cea708 minimum color list */
|
||||||
|
#define CEA708_COLOR_INVALID 0xFF
|
||||||
|
#define CEA708_COLOR_BLACK 0x00
|
||||||
|
#define CEA708_COLOR_WHITE 0x2A
|
||||||
|
#define CEA708_COLOR_RED 0x20
|
||||||
|
#define CEA708_COLOR_GREEN 0x08
|
||||||
|
#define CEA708_COLOR_BLUE 0x02
|
||||||
|
#define CEA708_COLOR_YELLOW 0x28
|
||||||
|
#define CEA708_COLOR_MAGENTA 0x22
|
||||||
|
#define CEA708_COLOR_CYAN 0x0A
|
||||||
|
#define CEA708_PANGO_SPAN_MARKUP_START "<span"
|
||||||
|
#define CEA708_PANGO_SPAN_MARKUP_END "</span>"
|
||||||
|
#define CEA708_PANGO_SPAN_ATTRIBUTES_UNDERLINE_SINGLE " underline='single'"
|
||||||
|
#define CEA708_PANGO_SPAN_ATTRIBUTES_STYLE_ITALIC " style='italic'"
|
||||||
|
#define CEA708_PANGO_SPAN_ATTRIBUTES_FONT " font_desc="
|
||||||
|
#define CEA708_PANGO_SPAN_ATTRIBUTES_FOREGROUND " foreground="
|
||||||
|
#define CEA708_PANGO_SPAN_ATTRIBUTES_BACKGROUND " background="
|
||||||
|
#define MINIMUM_OUTLINE_OFFSET 1.0
|
||||||
|
#define WINDOW_IN_LIST_IS_ACTIVE(list) (list & 0x1)
|
||||||
|
typedef struct _Cea708Dec Cea708Dec;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
COLOR_TYPE_BLACK = 0,
|
||||||
|
COLOR_TYPE_WHITE,
|
||||||
|
COLOR_TYPE_RED,
|
||||||
|
COLOR_TYPE_GREEN,
|
||||||
|
COLOR_TYPE_BLUE,
|
||||||
|
COLOR_TYPE_YELLOW,
|
||||||
|
COLOR_TYPE_MAGENTA,
|
||||||
|
COLOR_TYPE_CYAN,
|
||||||
|
COLOR_TYPE_RESEVER
|
||||||
|
} Cea708ColorType;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
NO_CHANGE = 0,
|
||||||
|
SWITCH_TO_HIDE,
|
||||||
|
SWITCH_TO_SHOW,
|
||||||
|
TOGGLE
|
||||||
|
} VisibilityControl;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
SOLID = 0,
|
||||||
|
FLASH,
|
||||||
|
TRANSLUCENT,
|
||||||
|
TRANSPARENT
|
||||||
|
} Opacity;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
WIN_STYLE_NORMAL = 1,
|
||||||
|
WIN_STYLE_TRANSPARENT,
|
||||||
|
WIN_STYLE_NORMAL_CENTERED,
|
||||||
|
WIN_STYLE_NORMAL_WORD_WRAP,
|
||||||
|
WIN_STYLE_TRANSPARENT_WORD_WRAP,
|
||||||
|
WIN_STYLE_TRANSPARENT_CENTERED,
|
||||||
|
WIN_STYLE_ROTATED
|
||||||
|
} WindowStyle;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
PEN_STYLE_DEFAULT = 1,
|
||||||
|
PEN_STYLE_MONO_SERIF,
|
||||||
|
PEN_STYLE_PROP_SERIF,
|
||||||
|
PEN_STYLE_MONO_SANS,
|
||||||
|
PEN_STYLE_PROP_SANS,
|
||||||
|
PEN_STYLE_MONO_SANS_TRANSPARENT,
|
||||||
|
PEN_STYLE_PROP_SANS_TRANSPARENT
|
||||||
|
} PenStyle;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ANCHOR_PT_TOP_LEFT = 0,
|
||||||
|
ANCHOR_PT_TOP_CENTER,
|
||||||
|
ANCHOR_PT_TOP_RIGHT,
|
||||||
|
ANCHOR_PT_MIDDLE_LEFT,
|
||||||
|
ANCHOR_PT_CENTER,
|
||||||
|
ANCHOR_PT_MIDDLE_RIGHT,
|
||||||
|
ANCHOR_PT_BOTTOM_LEFT,
|
||||||
|
ANCHOR_PT_BOTTOM_CENTER,
|
||||||
|
ANCHOR_PT_BOTTOM_RIGHT,
|
||||||
|
} AnchorPoint;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
TAG_DIALOG = 0,
|
||||||
|
TAG_SPEAKER_ID,
|
||||||
|
TAG_ELECTRONIC_VOICE,
|
||||||
|
TAG_ALT_LANGUAGE_DIALOG,
|
||||||
|
TAG_VOICEOVER,
|
||||||
|
TAG_AUDIBLE_TRANSLATION,
|
||||||
|
TAG_SUBTITLE_TRANSLATION,
|
||||||
|
TAG_VOICE_QUALITY_DESCRIPTION,
|
||||||
|
TAG_SONG_LYRICS,
|
||||||
|
TAG_SOUND_EFFECT_DESCRIPTION,
|
||||||
|
TAG_MUSICAL_SCORE_DESCRIPTION,
|
||||||
|
TAG_EXPLETIVE,
|
||||||
|
TAG_UNDEF1,
|
||||||
|
TAG_UNDEF2,
|
||||||
|
TAG_UNDEF3,
|
||||||
|
TAG_NOT_DISPLAYED
|
||||||
|
} TagType;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
JUSTIFY_LEFT = 0,
|
||||||
|
JUSTIFY_RIGHT,
|
||||||
|
JUSTIFY_CENTER,
|
||||||
|
JUSTIFY_FULL
|
||||||
|
} JUSTIFY_MODE;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
PRINT_DIR_LEFT_TO_RIGHT = 0,
|
||||||
|
PRINT_DIR_RIGHT_TO_LEFT,
|
||||||
|
PRINT_DIR_TOP_TO_BOTTOM,
|
||||||
|
PRINT_DIR_BOTTOM_TO_TOP
|
||||||
|
} PRINT_DIRECTION;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
SCROLL_DIR_LEFT_TO_RIGHT = 0,
|
||||||
|
SCROLL_DIR_RIGHT_TO_LEFT,
|
||||||
|
SCROLL_DIR_TOP_TO_BOTTOM,
|
||||||
|
SCROLL_DIR_BOTTOM_TO_TOP
|
||||||
|
} SCROLL_DIRECTION;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
DISPLAY_EFFECT_SNAP = 0,
|
||||||
|
DISPLAY_EFFECT_FADE,
|
||||||
|
DISPLAY_EFFECT_WIPE
|
||||||
|
} DisplayEffect;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
EFFECT_DIR_LEFT_TO_RIGHT = 0,
|
||||||
|
EFFECT_DIR_RIGHT_TO_LEFT,
|
||||||
|
EFFECT_DIR_TOP_TO_BOTTOM,
|
||||||
|
EFFECT_DIR_BOTTOM_TO_TOP
|
||||||
|
} EFFECT_DIRECTION;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
BORDER_TYPE_NONE = 0,
|
||||||
|
BORDER_TYPE_RAISED,
|
||||||
|
BORDER_TYPE_DEPRESSED,
|
||||||
|
BORDER_TYPE_UNIFORM
|
||||||
|
} BORDER_TYPE;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
PEN_SIZE_SMALL = 0,
|
||||||
|
PEN_SIZE_STANDARD,
|
||||||
|
PEN_SIZE_LARGE,
|
||||||
|
PEN_SIZE_INVALID
|
||||||
|
} PenSize;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
PEN_OFFSET_SUBSCRIPT = 0,
|
||||||
|
PEN_OFFSET_NORMAL,
|
||||||
|
PEN_OFFSET_SUPERSCRIPT,
|
||||||
|
PEN_OFFSET_INVALID
|
||||||
|
} PenOffset;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
EDGE_TYPE_NONE = 0,
|
||||||
|
EDGE_TYPE_RAISED,
|
||||||
|
EDGE_TYPE_DEPRESSED,
|
||||||
|
EDGE_TYPE_UNIFORM,
|
||||||
|
EDGE_TYPE_LEFT_DROP_SHADOW,
|
||||||
|
EDGE_TYPE_RIGHT_DROP_SHADOW,
|
||||||
|
EDGE_TYPE_INVALID_1,
|
||||||
|
EDGE_TYPE_INVALID_2
|
||||||
|
} EdgeType;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
FONT_STYLE_DEFAULT = 0,
|
||||||
|
FONT_STYLE_MONO_SERIF,
|
||||||
|
FONT_STYLE_PROP_SERIF,
|
||||||
|
FONT_STYLE_MONO_SANS,
|
||||||
|
FONT_STYLE_PROP_SANS,
|
||||||
|
FONT_STYLE_CASUAL,
|
||||||
|
FONT_STYLE_CURSIVE,
|
||||||
|
FONT_STYLE_SMALLCAPS
|
||||||
|
} FontStyle;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
guint8 fg_color;
|
||||||
|
guint8 fg_opacity;
|
||||||
|
guint8 bg_color;
|
||||||
|
guint8 bg_opacity;
|
||||||
|
guint8 edge_color;
|
||||||
|
} cea708PenColor;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
gboolean span_start_flag;
|
||||||
|
gboolean span_end_flag;
|
||||||
|
gboolean span_txt_flag;
|
||||||
|
|
||||||
|
gboolean span_next_flag;
|
||||||
|
|
||||||
|
gboolean underline;
|
||||||
|
gboolean italics;
|
||||||
|
|
||||||
|
guint8 size;
|
||||||
|
guint8 fg_color;
|
||||||
|
guint8 bg_color;
|
||||||
|
FontStyle font_style;
|
||||||
|
} cea708PangoSpanControl;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
PenSize pen_size;
|
||||||
|
FontStyle font_style;
|
||||||
|
TagType text_tag;
|
||||||
|
PenOffset offset;
|
||||||
|
gboolean italics;
|
||||||
|
gboolean underline;
|
||||||
|
EdgeType edge_type;
|
||||||
|
} cea708PenAttributes;
|
||||||
|
|
||||||
|
/* The char records one cell location in the window, with the character and all of its attributes */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
cea708PenColor pen_color;
|
||||||
|
cea708PenAttributes pen_attributes;
|
||||||
|
guint8 justify_mode;
|
||||||
|
gunichar c;
|
||||||
|
} cea708char;
|
||||||
|
|
||||||
|
|
||||||
|
/* This struct keeps track of one cea-708 CC window. There are up to 8. As new
|
||||||
|
* windows are created, the text they contain is visible on the screen (if the
|
||||||
|
* window visible flag is set). When a window is deleted, all text within the
|
||||||
|
* window is erased from the screen. Windows may be initialized and made visible
|
||||||
|
* then hidden. Each transition should cause new text cues to be emitted as
|
||||||
|
* text is displayed and removed from the screen.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/* The current attributes which will be used for the next text string */
|
||||||
|
cea708PenColor pen_color;
|
||||||
|
cea708PenAttributes pen_attributes;
|
||||||
|
|
||||||
|
/* true to indicate the window has not been created.
|
||||||
|
* set to true on delete, false on subsequent define command
|
||||||
|
* if true, reset pen position to 0,0 on window creation
|
||||||
|
*/
|
||||||
|
gboolean deleted;
|
||||||
|
|
||||||
|
/* Text position */
|
||||||
|
guint16 pen_row;
|
||||||
|
guint16 pen_col;
|
||||||
|
/* window display priority */
|
||||||
|
guint8 priority;
|
||||||
|
/* window position on screen 0-8 */
|
||||||
|
guint8 anchor_point;
|
||||||
|
/* 1 = anchor vertical/horizontal coordinates, 0 = physical screen coordinate, aka. rp */
|
||||||
|
guint8 relative_position;
|
||||||
|
/* vertical position of windows anchor point, 0-74 or if rp=1 then 0-99 */
|
||||||
|
guint8 anchor_vertical;
|
||||||
|
/* horz position of window anchor point, 0-209(16:9) 0-159(4:3) or if rp=1 then 0-99 */
|
||||||
|
guint8 anchor_horizontal;
|
||||||
|
/* vert position of upper left corner of window */
|
||||||
|
gfloat screen_vertical;
|
||||||
|
/* horz position of upper left corner of window */
|
||||||
|
gfloat screen_horizontal;
|
||||||
|
/* virtual rows of text - 1, (ex. rc=2 means there are 3 rows) */
|
||||||
|
guint8 row_count;
|
||||||
|
/* virtual columns of text, 0-41(16:9) 0-31(4:3) - 1 */
|
||||||
|
guint8 column_count;
|
||||||
|
/* 1 = fixes #rows of caption text, 0 = more rows may be added */
|
||||||
|
guint8 row_lock;
|
||||||
|
/* 1 = fixes #columns of caption text, 0 = more columns may be added */
|
||||||
|
guint8 column_lock;
|
||||||
|
/* TRUE = window is visible, FALSE = window not visible */
|
||||||
|
gboolean visible;
|
||||||
|
/* specifies 1 of 7 static preset window. attribute styles, during window create,
|
||||||
|
* 0 = use style #1, during window update, 0 = no window, attributes will be changed
|
||||||
|
*/
|
||||||
|
guint8 style_id;
|
||||||
|
/* specifies 1 of 7 static preset pen attributes, during window create,
|
||||||
|
* 0 = use pen style #1, during window update, 0 = do not change pen attributes
|
||||||
|
*/
|
||||||
|
guint8 pen_style_id;
|
||||||
|
/* timestamp when this window became visible */
|
||||||
|
guint64 start_time;
|
||||||
|
|
||||||
|
/* window attributes */
|
||||||
|
guint8 justify_mode;
|
||||||
|
guint8 print_direction;
|
||||||
|
guint8 scroll_direction;
|
||||||
|
gboolean word_wrap;
|
||||||
|
guint8 display_effect;
|
||||||
|
guint8 effect_direction;
|
||||||
|
guint8 effect_speed;
|
||||||
|
guint8 fill_color;
|
||||||
|
guint8 fill_opacity;
|
||||||
|
guint8 border_type;
|
||||||
|
guint8 border_color;
|
||||||
|
|
||||||
|
/* Character position offsets for the upper left corner of the window */
|
||||||
|
guint v_offset;
|
||||||
|
guint h_offset;
|
||||||
|
|
||||||
|
/* The char array that text is written into, using the current pen position */
|
||||||
|
cea708char text[WINDOW_MAX_ROWS][WINDOW_MAX_COLS];
|
||||||
|
|
||||||
|
PangoLayout *layout;
|
||||||
|
gdouble shadow_offset;
|
||||||
|
gdouble outline_offset;
|
||||||
|
guchar *text_image;
|
||||||
|
gint image_width;
|
||||||
|
gint image_height;
|
||||||
|
gboolean updated;
|
||||||
|
} cea708Window;
|
||||||
|
|
||||||
|
struct _Cea708Dec
|
||||||
|
{
|
||||||
|
/* output data storage */
|
||||||
|
GSList *text_list;
|
||||||
|
|
||||||
|
/* simulation of 708 CC windows */
|
||||||
|
cea708Window *cc_windows[MAX_708_WINDOWS];
|
||||||
|
guint8 current_window;
|
||||||
|
gchar *default_font_desc;
|
||||||
|
PangoContext *pango_context;
|
||||||
|
|
||||||
|
/* a counter used to ignore bytes in CC text stream following commands */
|
||||||
|
gint8 output_ignore;
|
||||||
|
/* most recent timestamp from userdata */
|
||||||
|
guint64 current_time;
|
||||||
|
|
||||||
|
/* desired_service selects the service that will be decoded. If
|
||||||
|
* desired_service = -1 (default) no decoding based on service number will
|
||||||
|
* occur. Service #0 is reserved, and the valid range of service numbers
|
||||||
|
* is 1-7. with 1 being primary caption service and 2 being the secondary
|
||||||
|
* language service. If service_number is 7, then the extended_service_number is added and used instead of the service_number */
|
||||||
|
gint8 desired_service;
|
||||||
|
|
||||||
|
gboolean use_ARGB;
|
||||||
|
gint width;
|
||||||
|
gint height;
|
||||||
|
};
|
||||||
|
|
||||||
|
Cea708Dec *gst_cea708dec_create (PangoContext * pango_context);
|
||||||
|
void
|
||||||
|
gst_cea708dec_set_service_number (Cea708Dec * decoder, gint8 desired_service);
|
||||||
|
gboolean
|
||||||
|
gst_cea708dec_process_dtvcc_packet (Cea708Dec * decoder, guint8 * dtvcc_buffer, gsize dtvcc_size);
|
||||||
|
void
|
||||||
|
gst_cea708dec_set_video_width_height (Cea708Dec * decoder, gint width, gint height);
|
||||||
|
void gst_cea708_decoder_init_debug(void);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
#endif /* __GST_CEA708_DEC_H__ */
|
1957
ext/closedcaption/gstceaccoverlay.c
Normal file
1957
ext/closedcaption/gstceaccoverlay.c
Normal file
File diff suppressed because it is too large
Load diff
136
ext/closedcaption/gstceaccoverlay.h
Normal file
136
ext/closedcaption/gstceaccoverlay.h
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
/* GStreamer
|
||||||
|
* Copyright (C) 2015 Samsung Electronics Co., Ltd.
|
||||||
|
* @Author: Chengjun Wang <cjun.wang@samsung.com>
|
||||||
|
*
|
||||||
|
* 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., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __GST_CEA_CC_OVERLAY_H__
|
||||||
|
#define __GST_CEA_CC_OVERLAY_H__
|
||||||
|
|
||||||
|
#include <gst/gst.h>
|
||||||
|
#include <pango/pangocairo.h>
|
||||||
|
#include <gstcea708decoder.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
#define GST_TYPE_CEA_CC_OVERLAY \
|
||||||
|
(gst_cea_cc_overlay_get_type())
|
||||||
|
#define GST_CEA_CC_OVERLAY(obj) \
|
||||||
|
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CEA_CC_OVERLAY,GstCeaCcOverlay))
|
||||||
|
#define GST_CEA_CC_OVERLAY_CLASS(klass) \
|
||||||
|
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CEA_CC_OVERLAY,GstCeaCcOverlayClass))
|
||||||
|
#define GST_CEA_CC_OVERLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),\
|
||||||
|
GST_TYPE_CEA_CC_OVERLAY, GstCeaCcOverlayClass))
|
||||||
|
#define GST_IS_CEA_CC_OVERLAY(obj) \
|
||||||
|
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CEA_CC_OVERLAY))
|
||||||
|
#define GST_IS_CEA_CC_OVERLAY_CLASS(klass) \
|
||||||
|
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CEA_CC_OVERLAY))
|
||||||
|
|
||||||
|
typedef struct _GstCeaCcOverlay GstCeaCcOverlay;
|
||||||
|
typedef struct _GstCeaCcOverlayClass GstCeaCcOverlayClass;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
CCTYPE_608_CC1 = 0,
|
||||||
|
CCTYPE_608_CC2,
|
||||||
|
CCTYPE_708_ADD,
|
||||||
|
CCTYPE_708_START,
|
||||||
|
} DtvccType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstBaseTextOverlayHAlign:
|
||||||
|
* @GST_CEA_CC_OVERLAY_WIN_H_LEFT: closed caption window horizontal anchor left
|
||||||
|
* @GST_CEA_CC_OVERLAY_WIN_H_CENTER: closed caption window horizontal anchor center
|
||||||
|
* @GST_CEA_CC_OVERLAY_WIN_H_RIGHT: closed caption window horizontal anchor right
|
||||||
|
* @GST_CEA_CC_OVERLAY_WIN_H_AUTO: closed caption window horizontal anchor auto
|
||||||
|
*
|
||||||
|
* Closed Caption Window Horizontal anchor position.
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GST_CEA_CC_OVERLAY_WIN_H_LEFT,
|
||||||
|
GST_CEA_CC_OVERLAY_WIN_H_CENTER,
|
||||||
|
GST_CEA_CC_OVERLAY_WIN_H_RIGHT,
|
||||||
|
GST_CEA_CC_OVERLAY_WIN_H_AUTO
|
||||||
|
} GstCeaCcOverlayWinHPos;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstCeaCcOverlay:
|
||||||
|
*
|
||||||
|
* Opaque ccoverlay data structure.
|
||||||
|
*/
|
||||||
|
struct _GstCeaCcOverlay
|
||||||
|
{
|
||||||
|
GstElement parent;
|
||||||
|
GstPad *video_sinkpad;
|
||||||
|
GstPad *cc_sinkpad;
|
||||||
|
GstPad *srcpad;
|
||||||
|
/* There are two possible 608 streams encapsulated by 708 */
|
||||||
|
gint16 cea608_index[NUM_608_CCTYPES];
|
||||||
|
gint16 cea708_index;
|
||||||
|
guint8 cea608_buffer[NUM_608_CCTYPES][DTVCC_LENGTH];
|
||||||
|
guint8 cea708_buffer[DTVCC_LENGTH];
|
||||||
|
|
||||||
|
/* TRUE if input is CDP, FALSE if cc_data triplet */
|
||||||
|
gboolean is_cdp;
|
||||||
|
|
||||||
|
GstSegment segment;
|
||||||
|
GstSegment cc_segment;
|
||||||
|
GstVideoOverlayComposition *current_composition;
|
||||||
|
guint64 current_comp_start_time;
|
||||||
|
GstVideoOverlayComposition *next_composition;
|
||||||
|
guint64 next_comp_start_time;
|
||||||
|
GstCeaCcOverlayWinHPos default_window_h_pos;
|
||||||
|
gboolean cc_pad_linked;
|
||||||
|
gboolean video_flushing;
|
||||||
|
gboolean video_eos;
|
||||||
|
gboolean cc_flushing;
|
||||||
|
gboolean cc_eos;
|
||||||
|
|
||||||
|
GMutex lock;
|
||||||
|
GCond cond; /* to signal removal of a queued text
|
||||||
|
* buffer, arrival of a text buffer,
|
||||||
|
* a text segment update, or a change
|
||||||
|
* in status (e.g. shutdown, flushing) */
|
||||||
|
|
||||||
|
GstVideoInfo info;
|
||||||
|
GstVideoFormat format;
|
||||||
|
gint width;
|
||||||
|
gint height;
|
||||||
|
gboolean silent;
|
||||||
|
Cea708Dec *decoder;
|
||||||
|
gint image_width;
|
||||||
|
gint image_height;
|
||||||
|
|
||||||
|
gboolean need_update;
|
||||||
|
|
||||||
|
gboolean attach_compo_to_buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* FIXME : Pango context and MT-safe since 1.32.6 */
|
||||||
|
struct _GstCeaCcOverlayClass
|
||||||
|
{
|
||||||
|
GstElementClass parent_class;
|
||||||
|
|
||||||
|
PangoContext *pango_context;
|
||||||
|
GMutex *pango_lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
GType gst_cea_cc_overlay_get_type (void);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
#endif /* __GST_CEA_CC_OVERLAY_H__ */
|
|
@ -27,18 +27,22 @@
|
||||||
|
|
||||||
#include "gstccextractor.h"
|
#include "gstccextractor.h"
|
||||||
#include "gstline21dec.h"
|
#include "gstline21dec.h"
|
||||||
|
#include "gstceaccoverlay.h"
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
closedcaption_init (GstPlugin * ccextractor)
|
closedcaption_init (GstPlugin * plugin)
|
||||||
{
|
{
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
|
|
||||||
ret = gst_element_register (ccextractor, "ccextractor", GST_RANK_NONE,
|
ret = gst_element_register (plugin, "ccextractor", GST_RANK_NONE,
|
||||||
GST_TYPE_CCEXTRACTOR);
|
GST_TYPE_CCEXTRACTOR);
|
||||||
|
|
||||||
ret &= gst_element_register (ccextractor, "line21decoder", GST_RANK_NONE,
|
ret &= gst_element_register (plugin, "line21decoder", GST_RANK_NONE,
|
||||||
GST_TYPE_LINE21DECODER);
|
GST_TYPE_LINE21DECODER);
|
||||||
|
|
||||||
|
ret = gst_element_register (plugin, "cc708overlay", GST_RANK_PRIMARY,
|
||||||
|
GST_TYPE_CEA_CC_OVERLAY);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,8 @@ zvbi_sources = [
|
||||||
|
|
||||||
if pangocairo_dep.found()
|
if pangocairo_dep.found()
|
||||||
gstclosedcaption = library('gstclosedcaption',
|
gstclosedcaption = library('gstclosedcaption',
|
||||||
'gstccextractor.c', 'gstclosedcaption.c', 'gstline21dec.c', zvbi_sources,
|
'gstccextractor.c', 'gstclosedcaption.c', 'gstline21dec.c',
|
||||||
|
'gstcea708decoder.c', 'gstceaccoverlay.c', zvbi_sources,
|
||||||
c_args : gst_plugins_bad_args,
|
c_args : gst_plugins_bad_args,
|
||||||
link_args : noseh_link_args,
|
link_args : noseh_link_args,
|
||||||
include_directories : [configinc],
|
include_directories : [configinc],
|
||||||
|
|
Loading…
Reference in a new issue