• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GStreamer
2  * Copyright (C) 2013 CableLabs, Louisville, CO 80027
3  * Copyright (C) 2015 Samsung Electronics Co., Ltd.
4  *     @Author: Chengjun Wang <cjun.wang@samsung.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21 
22 
23 #ifndef __GST_CEA708_DEC_H__
24 #define __GST_CEA708_DEC_H__
25 
26 #include <gst/gst.h>
27 #include <pango/pangocairo.h>
28 
29 G_BEGIN_DECLS
30 /* from ATSC A/53 Part 4
31  * DTVCC packets are 128 bytes MAX, length is only 6 bits, header is 2 bytes,
32  * the last byte is flag-fill, that leaves 125 possible bytes of data to be
33  * represented in 6 bits, hence the length encoding
34  */
35 /* should never be more than 128 */
36 #define DTVCC_LENGTH       128
37 #define DTVCC_PKT_SIZE(sz_byte)  (((sz_byte) == 0) ? 127 : ((sz_byte)  * 2) -1)
38 #define CCTYPE_VALID_MASK  0x04
39 #define CCTYPE_TYPE_MASK   0x03
40 #define NUM_608_CCTYPES 2
41 /* CEA-708-B commands */
42 /* EndOfText */
43 #define CC_COMMAND_ETX 0x03
44 /* SetCurrentWindow0 */
45 #define CC_COMMAND_CW0 0x80
46 #define CC_COMMAND_CW1 0x81
47 #define CC_COMMAND_CW2 0x82
48 #define CC_COMMAND_CW3 0x83
49 #define CC_COMMAND_CW4 0x84
50 #define CC_COMMAND_CW5 0x85
51 #define CC_COMMAND_CW6 0x86
52 #define CC_COMMAND_CW7 0x87
53 /* ClearWindows */
54 #define CC_COMMAND_CLW 0x88
55 /* DisplayWindows */
56 #define CC_COMMAND_DSW 0x89
57 /* HideWindows */
58 #define CC_COMMAND_HDW 0x8A
59 /* ToggleWindows */
60 #define CC_COMMAND_TGW 0x8B
61 /* DeleteWindows */
62 #define CC_COMMAND_DLW 0x8C
63 /* Delay */
64 #define CC_COMMAND_DLY 0x8D
65 /* DelayCancel */
66 #define CC_COMMAND_DLC 0x8E
67 /* Reset */
68 #define CC_COMMAND_RST 0x8F
69 /* SetPenAttributes */
70 #define CC_COMMAND_SPA 0x90
71 /* SetPenColor */
72 #define CC_COMMAND_SPC 0x91
73 /* SetPenLocation */
74 #define CC_COMMAND_SPL 0x92
75 /* SetWindowAttributes */
76 #define CC_COMMAND_SWA 0x97
77 /* DefineWindow0 */
78 #define CC_COMMAND_DF0 0x98
79 #define CC_COMMAND_DF1 0x99
80 #define CC_COMMAND_DF2 0x9A
81 #define CC_COMMAND_DF3 0x9B
82 #define CC_COMMAND_DF4 0x9C
83 #define CC_COMMAND_DF5 0x9D
84 #define CC_COMMAND_DF6 0x9E
85 #define CC_COMMAND_DF7 0x9F
86 /* music note unicode */
87 #define CC_SPECIAL_CODE_MUSIC_NOTE    0x266a
88 #define CC_UTF8_MAX_LENGTH   6
89 #define CC_MAX_CODE_SET_SIZE   96
90 /* Per CEA-708 spec there may be 8 CC windows */
91 #define MAX_708_WINDOWS  8
92 /* Each 708 window contains a grid of character positions. These are the
93   * max limits defined, but each window has a row/col count which is typically
94   * smaller than the limits. Note this is just one window, not the entire screen.
95   */
96 /* max row count */
97 #define WINDOW_MAX_ROWS 15
98 /* max column width */
99 #define WINDOW_MAX_COLS 42
100 /* The linebuffer contains text for 1 line pango text corresponding to 1 line of 708 text.
101   * The linebuffer could be a lot larger than the window text because of required markup.
102   * example <u> </u> for underline.
103   * The size given is an estimate, to be changed if determined that a larger
104   * buffer is needed
105   */
106 #define LINEBUFFER_SIZE 1024
107 /* The screen width/height defined by 708 - not character units, these are
108   * used only to determine the position of the anchor on the screen.
109   */
110 #define SCREEN_WIDTH_16_9    209
111 #define SCREEN_HEIGHT_16_9   74
112 #define SCREEN_WIDTH_4_3    159
113 #define SCREEN_HEIGHT_4_3    74
114 
115 /* raw bytes of "define window" command */
116 #define WIN_DEF_SIZE 6
117 /* The maximum size of a 708 window in character units. This is used to
118   * calculate the position of windows based on window anchor positions.
119   */
120 #define SCREEN_HEIGHT_708  15
121 #define SCREEN_WIDTH_708   32
122 /* cea708 minimum color list */
123 #define CEA708_COLOR_INVALID   0xFF
124 #define CEA708_COLOR_BLACK     0x00
125 #define CEA708_COLOR_WHITE     0x2A
126 #define CEA708_COLOR_RED       0x20
127 #define CEA708_COLOR_GREEN     0x08
128 #define CEA708_COLOR_BLUE      0x02
129 #define CEA708_COLOR_YELLOW    0x28
130 #define CEA708_COLOR_MAGENTA   0x22
131 #define CEA708_COLOR_CYAN      0x0A
132 #define CEA708_PANGO_SPAN_MARKUP_START                      "<span"
133 #define CEA708_PANGO_SPAN_MARKUP_END                        "</span>"
134 #define CEA708_PANGO_SPAN_ATTRIBUTES_UNDERLINE_SINGLE       " underline='single'"
135 #define CEA708_PANGO_SPAN_ATTRIBUTES_STYLE_ITALIC           " style='italic'"
136 #define CEA708_PANGO_SPAN_ATTRIBUTES_FONT                   " font_desc="
137 #define CEA708_PANGO_SPAN_ATTRIBUTES_FOREGROUND             " foreground="
138 #define CEA708_PANGO_SPAN_ATTRIBUTES_BACKGROUND             " background="
139 #define MINIMUM_OUTLINE_OFFSET 1.0
140 #define WINDOW_IN_LIST_IS_ACTIVE(list) (list & 0x1)
141 typedef struct _Cea708Dec Cea708Dec;
142 
143 typedef enum
144 {
145   COLOR_TYPE_BLACK = 0,
146   COLOR_TYPE_WHITE,
147   COLOR_TYPE_RED,
148   COLOR_TYPE_GREEN,
149   COLOR_TYPE_BLUE,
150   COLOR_TYPE_YELLOW,
151   COLOR_TYPE_MAGENTA,
152   COLOR_TYPE_CYAN,
153   COLOR_TYPE_RESEVER
154 } Cea708ColorType;
155 
156 typedef enum
157 {
158   NO_CHANGE = 0,
159   SWITCH_TO_HIDE,
160   SWITCH_TO_SHOW,
161   TOGGLE
162 } VisibilityControl;
163 
164 typedef enum
165 {
166   SOLID = 0,
167   FLASH,
168   TRANSLUCENT,
169   TRANSPARENT
170 } Opacity;
171 
172 typedef enum
173 {
174   WIN_STYLE_NORMAL = 1,
175   WIN_STYLE_TRANSPARENT,
176   WIN_STYLE_NORMAL_CENTERED,
177   WIN_STYLE_NORMAL_WORD_WRAP,
178   WIN_STYLE_TRANSPARENT_WORD_WRAP,
179   WIN_STYLE_TRANSPARENT_CENTERED,
180   WIN_STYLE_ROTATED
181 } WindowStyle;
182 
183 typedef enum
184 {
185   PEN_STYLE_DEFAULT = 1,
186   PEN_STYLE_MONO_SERIF,
187   PEN_STYLE_PROP_SERIF,
188   PEN_STYLE_MONO_SANS,
189   PEN_STYLE_PROP_SANS,
190   PEN_STYLE_MONO_SANS_TRANSPARENT,
191   PEN_STYLE_PROP_SANS_TRANSPARENT
192 } PenStyle;
193 
194 typedef enum
195 {
196   ANCHOR_PT_TOP_LEFT = 0,
197   ANCHOR_PT_TOP_CENTER,
198   ANCHOR_PT_TOP_RIGHT,
199   ANCHOR_PT_MIDDLE_LEFT,
200   ANCHOR_PT_CENTER,
201   ANCHOR_PT_MIDDLE_RIGHT,
202   ANCHOR_PT_BOTTOM_LEFT,
203   ANCHOR_PT_BOTTOM_CENTER,
204   ANCHOR_PT_BOTTOM_RIGHT,
205 } AnchorPoint;
206 
207 typedef enum
208 {
209   TAG_DIALOG = 0,
210   TAG_SPEAKER_ID,
211   TAG_ELECTRONIC_VOICE,
212   TAG_ALT_LANGUAGE_DIALOG,
213   TAG_VOICEOVER,
214   TAG_AUDIBLE_TRANSLATION,
215   TAG_SUBTITLE_TRANSLATION,
216   TAG_VOICE_QUALITY_DESCRIPTION,
217   TAG_SONG_LYRICS,
218   TAG_SOUND_EFFECT_DESCRIPTION,
219   TAG_MUSICAL_SCORE_DESCRIPTION,
220   TAG_EXPLETIVE,
221   TAG_UNDEF1,
222   TAG_UNDEF2,
223   TAG_UNDEF3,
224   TAG_NOT_DISPLAYED
225 } TagType;
226 
227 typedef enum
228 {
229   JUSTIFY_LEFT = 0,
230   JUSTIFY_RIGHT,
231   JUSTIFY_CENTER,
232   JUSTIFY_FULL
233 } JUSTIFY_MODE;
234 
235 typedef enum
236 {
237   PRINT_DIR_LEFT_TO_RIGHT = 0,
238   PRINT_DIR_RIGHT_TO_LEFT,
239   PRINT_DIR_TOP_TO_BOTTOM,
240   PRINT_DIR_BOTTOM_TO_TOP
241 } PRINT_DIRECTION;
242 
243 typedef enum
244 {
245   SCROLL_DIR_LEFT_TO_RIGHT = 0,
246   SCROLL_DIR_RIGHT_TO_LEFT,
247   SCROLL_DIR_TOP_TO_BOTTOM,
248   SCROLL_DIR_BOTTOM_TO_TOP
249 } SCROLL_DIRECTION;
250 
251 typedef enum
252 {
253   DISPLAY_EFFECT_SNAP = 0,
254   DISPLAY_EFFECT_FADE,
255   DISPLAY_EFFECT_WIPE
256 } DisplayEffect;
257 
258 typedef enum
259 {
260   EFFECT_DIR_LEFT_TO_RIGHT = 0,
261   EFFECT_DIR_RIGHT_TO_LEFT,
262   EFFECT_DIR_TOP_TO_BOTTOM,
263   EFFECT_DIR_BOTTOM_TO_TOP
264 } EFFECT_DIRECTION;
265 
266 typedef enum
267 {
268   BORDER_TYPE_NONE = 0,
269   BORDER_TYPE_RAISED,
270   BORDER_TYPE_DEPRESSED,
271   BORDER_TYPE_UNIFORM
272 } BORDER_TYPE;
273 
274 typedef enum
275 {
276   PEN_SIZE_SMALL = 0,
277   PEN_SIZE_STANDARD,
278   PEN_SIZE_LARGE,
279   PEN_SIZE_INVALID
280 } PenSize;
281 
282 typedef enum
283 {
284   PEN_OFFSET_SUBSCRIPT = 0,
285   PEN_OFFSET_NORMAL,
286   PEN_OFFSET_SUPERSCRIPT,
287   PEN_OFFSET_INVALID
288 } PenOffset;
289 
290 typedef enum
291 {
292   EDGE_TYPE_NONE = 0,
293   EDGE_TYPE_RAISED,
294   EDGE_TYPE_DEPRESSED,
295   EDGE_TYPE_UNIFORM,
296   EDGE_TYPE_LEFT_DROP_SHADOW,
297   EDGE_TYPE_RIGHT_DROP_SHADOW,
298   EDGE_TYPE_INVALID_1,
299   EDGE_TYPE_INVALID_2
300 } EdgeType;
301 
302 typedef enum
303 {
304   FONT_STYLE_DEFAULT = 0,
305   FONT_STYLE_MONO_SERIF,
306   FONT_STYLE_PROP_SERIF,
307   FONT_STYLE_MONO_SANS,
308   FONT_STYLE_PROP_SANS,
309   FONT_STYLE_CASUAL,
310   FONT_STYLE_CURSIVE,
311   FONT_STYLE_SMALLCAPS
312 } FontStyle;
313 
314 typedef struct
315 {
316   guint8 fg_color;
317   guint8 fg_opacity;
318   guint8 bg_color;
319   guint8 bg_opacity;
320   guint8 edge_color;
321 } cea708PenColor;
322 
323 typedef struct
324 {
325   gboolean span_start_flag;
326   gboolean span_end_flag;
327   gboolean span_txt_flag;
328 
329   gboolean span_next_flag;
330 
331   gboolean underline;
332   gboolean italics;
333 
334   guint8 size;
335   guint8 fg_color;
336   guint8 bg_color;
337   FontStyle font_style;
338 } cea708PangoSpanControl;
339 
340 typedef struct
341 {
342   PenSize pen_size;
343   FontStyle font_style;
344   TagType text_tag;
345   PenOffset offset;
346   gboolean italics;
347   gboolean underline;
348   EdgeType edge_type;
349 } cea708PenAttributes;
350 
351 /* The char records one cell location in the window, with the character and all of its attributes */
352 typedef struct
353 {
354   cea708PenColor pen_color;
355   cea708PenAttributes pen_attributes;
356   guint8 justify_mode;
357   gunichar c;
358 } cea708char;
359 
360 
361 /* This struct keeps track of one cea-708 CC window. There are up to 8. As new
362   * windows are created, the text they contain is visible on the screen (if the
363   * window visible flag is set). When a window is deleted, all text within the
364   * window is erased from the screen. Windows may be initialized and made visible
365   * then hidden. Each transition should cause new text cues to be emitted as
366   * text is displayed and removed from the screen.
367   */
368 typedef struct
369 {
370   /* The current attributes which will be used for the next text string */
371   cea708PenColor pen_color;
372   cea708PenAttributes pen_attributes;
373 
374   /* true to indicate the window has not been created.
375    * set to true on delete, false on subsequent define command
376    * if true, reset pen position to 0,0 on window creation
377    */
378   gboolean deleted;
379 
380   /* Text position */
381   guint16 pen_row;
382   guint16 pen_col;
383   /* window display priority */
384   guint8 priority;
385   /* window position on screen 0-8 */
386   guint8 anchor_point;
387   /* 1 = anchor vertical/horizontal coordinates, 0 = physical screen coordinate, aka. rp */
388   guint8 relative_position;
389   /* vertical position of windows anchor point, 0-74 or if rp=1 then 0-99 */
390   guint8 anchor_vertical;
391   /* horz position of window anchor point, 0-209(16:9) 0-159(4:3) or if rp=1 then 0-99 */
392   guint8 anchor_horizontal;
393   /* vert position of upper left corner of window */
394   gfloat screen_vertical;
395   /* horz position of upper left corner of window */
396   gfloat screen_horizontal;
397   /* virtual rows of text - 1, (ex. rc=2 means there are 3 rows) */
398   guint8 row_count;
399   /* virtual columns of text, 0-41(16:9) 0-31(4:3) - 1 */
400   guint8 column_count;
401   /* 1 = fixes #rows of caption text, 0 = more rows may be added */
402   guint8 row_lock;
403   /* 1 = fixes #columns of caption text, 0 = more columns may be added */
404   guint8 column_lock;
405   /* TRUE = window is visible, FALSE = window not visible */
406   gboolean visible;
407   /* specifies 1 of 7 static preset window. attribute styles, during window create,
408    * 0 = use style #1, during window update, 0 = no window, attributes will be changed
409    */
410   guint8 style_id;
411   /* specifies 1 of 7 static preset pen attributes, during window create,
412    * 0 = use pen style #1, during window update, 0 = do not change pen attributes
413    */
414   guint8 pen_style_id;
415   /* timestamp when this window became visible */
416   guint64 start_time;
417 
418   /* window attributes */
419   guint8 justify_mode;
420   guint8 print_direction;
421   guint8 scroll_direction;
422   gboolean word_wrap;
423   guint8 display_effect;
424   guint8 effect_direction;
425   guint8 effect_speed;
426   guint8 fill_color;
427   guint8 fill_opacity;
428   guint8 border_type;
429   guint8 border_color;
430 
431   /* Character position offsets for the upper left corner of the window */
432   guint v_offset;
433   guint h_offset;
434 
435   /* The char array that text is written into, using the current pen position */
436   cea708char text[WINDOW_MAX_ROWS][WINDOW_MAX_COLS];
437 
438   PangoLayout *layout;
439   gdouble shadow_offset;
440   gdouble outline_offset;
441   guchar *text_image;
442   gint image_width;
443   gint image_height;
444   gboolean updated;
445 } cea708Window;
446 
447 struct _Cea708Dec
448 {
449   /* output data storage */
450   GSList *text_list;
451 
452   /* simulation of 708 CC windows */
453   cea708Window *cc_windows[MAX_708_WINDOWS];
454   guint8 current_window;
455   gchar *default_font_desc;
456   PangoContext *pango_context;
457 
458   /* a counter used to ignore bytes in CC text stream following commands */
459   gint8 output_ignore;
460   /* most recent timestamp from userdata */
461   guint64 current_time;
462 
463   /* desired_service selects the service that will be decoded. If
464    * desired_service = -1 (default) no decoding based on service number will
465    * occur. Service #0 is reserved, and the valid range of service numbers
466    * is 1-7. with 1 being primary caption service and 2 being the secondary
467    * language service. If service_number is 7, then the extended_service_number is added and used instead of the service_number */
468   gint8 desired_service;
469 
470   gboolean use_ARGB;
471   gint width;
472   gint height;
473 };
474 
475 Cea708Dec *gst_cea708dec_create (PangoContext * pango_context);
476 
477 void       gst_cea708dec_free (Cea708Dec *dec);
478 
479 void
480 gst_cea708dec_set_service_number (Cea708Dec * decoder, gint8 desired_service);
481 gboolean
482 gst_cea708dec_process_dtvcc_packet (Cea708Dec * decoder, guint8 * dtvcc_buffer, gsize dtvcc_size);
483 void
484 gst_cea708dec_set_video_width_height (Cea708Dec * decoder, gint width, gint height);
485 void gst_cea708_decoder_init_debug(void);
486 
487   G_END_DECLS
488 #endif /* __GST_CEA708_DEC_H__ */
489