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