annotate sub/sub_cc.c @ 34756:df3ff52039fe

Add code to support CC subtitles in ASTC and MOV. Code to actually use these will be added later, since it needs special code in FFmpeg. Code for MOV is already read, ASTC might take longer.
author reimar
date Sat, 07 Apr 2012 00:10:27 +0000
parents 788175a8c14a
children 430e164238d1
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
1 /*
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
2 * decoder for Closed Captions
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
3 *
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
4 * This decoder relies on MPlayer's OSD to display subtitles.
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
5 * Be warned that decoding is somewhat preliminary, though it basically works.
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
6 *
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
7 * Most notably, only the text information is decoded as of now, discarding
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
8 * color, background and position info (see source below).
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
9 *
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
10 * uses source from the xine closed captions decoder
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
11 *
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
12 * Copyright (C) 2002 Matteo Giani
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
13 *
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
14 * This file is part of MPlayer.
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
15 *
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
16 * MPlayer is free software; you can redistribute it and/or modify
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
17 * it under the terms of the GNU General Public License as published by
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
18 * the Free Software Foundation; either version 2 of the License, or
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
19 * (at your option) any later version.
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
20 *
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
21 * MPlayer is distributed in the hope that it will be useful,
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
24 * GNU General Public License for more details.
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
25 *
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
26 * You should have received a copy of the GNU General Public License along
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
27 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
28 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
29 */
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
30
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
31 #include <stdio.h>
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
32 #include <stdlib.h>
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
33 #include <string.h>
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
34
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
35 #include "config.h"
34756
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
36 #include "mp_msg.h"
32464
22888a8cb312 Do not use a path for including files in the same directory.
reimar
parents: 32458
diff changeset
37 #include "sub_cc.h"
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
38
32464
22888a8cb312 Do not use a path for including files in the same directory.
reimar
parents: 32458
diff changeset
39 #include "subreader.h"
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
40
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
41 #include "libvo/video_out.h"
32467
fbe5c829c69b Move libvo/sub.[ch] from libvo to sub.
cigaes
parents: 32464
diff changeset
42 #include "sub.h"
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
43
34756
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
44 #include "libavutil/avutil.h"
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
45
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
46
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
47 #define CC_MAX_LINE_LENGTH 64
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
48
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
49 static char chartbl[128];
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
50
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
51 static subtitle buf1,buf2;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
52 static subtitle *fb,*bb;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
53
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
54 static unsigned int cursor_pos=0;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
55
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
56 static int initialized=0;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
57
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
58 #define CC_ROLLON 1
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
59 #define CC_ROLLUP 2
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
60
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
61 static int cc_mode=CC_ROLLON;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
62 static int cc_lines=4; ///< number of visible rows in CC roll-up mode, not used in CC roll-on mode
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
63
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
64 static void build_char_table(void)
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
65 {
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
66 int i;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
67 /* first the normal ASCII codes */
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
68 for (i = 0; i < 128; i++)
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
69 chartbl[i] = (char) i;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
70 /* now the special codes */
34702
788175a8c14a Do not use single quotes around hex literals
al
parents: 34693
diff changeset
71 chartbl[0x2a] = 0xe1; /* Latin Small Letter A with acute */
788175a8c14a Do not use single quotes around hex literals
al
parents: 34693
diff changeset
72 chartbl[0x5c] = 0xe9; /* Latin Small Letter E with acute */
788175a8c14a Do not use single quotes around hex literals
al
parents: 34693
diff changeset
73 chartbl[0x5e] = 0xed; /* Latin Small Letter I with acute */
788175a8c14a Do not use single quotes around hex literals
al
parents: 34693
diff changeset
74 chartbl[0x5f] = 0xf3; /* Latin Small Letter O with acute */
788175a8c14a Do not use single quotes around hex literals
al
parents: 34693
diff changeset
75 chartbl[0x60] = 0xfa; /* Latin Small Letter U with acute */
788175a8c14a Do not use single quotes around hex literals
al
parents: 34693
diff changeset
76 chartbl[0x7b] = 0xe7; /* Latin Small Letter C with cedilla */
788175a8c14a Do not use single quotes around hex literals
al
parents: 34693
diff changeset
77 chartbl[0x7c] = 0xf7; /* Division sign */
788175a8c14a Do not use single quotes around hex literals
al
parents: 34693
diff changeset
78 chartbl[0x7d] = 0xd1; /* Latin Capital letter N with tilde */
788175a8c14a Do not use single quotes around hex literals
al
parents: 34693
diff changeset
79 chartbl[0x7e] = 0xf1; /* Latin Small Letter N with tilde */
788175a8c14a Do not use single quotes around hex literals
al
parents: 34693
diff changeset
80 chartbl[0x7f] = 0xa4; /* Currency sign FIXME: this should be a solid block */
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
81 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
82
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
83 static void clear_buffer(subtitle *buf)
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
84 {
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
85 int i;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
86 buf->lines=0;
32511
b39155e98ac3 Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents: 32467
diff changeset
87 for (i = 0; i < SUB_MAX_TEXT; i++) {
b39155e98ac3 Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents: 32467
diff changeset
88 free(buf->text[i]);
b39155e98ac3 Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents: 32467
diff changeset
89 buf->text[i] = NULL;
b39155e98ac3 Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents: 32467
diff changeset
90 }
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
91 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
92
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
93
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
94 /**
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
95 \brief scroll buffer one line up
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
96 \param buf buffer to scroll
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
97 */
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
98 static void scroll_buffer(subtitle* buf)
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
99 {
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
100 int i;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
101
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
102 while(buf->lines > cc_lines)
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
103 {
32511
b39155e98ac3 Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents: 32467
diff changeset
104 free(buf->text[0]);
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
105
32512
024358659ebd Avoid unnecessary ().
reimar
parents: 32511
diff changeset
106 for(i = 0; i < buf->lines - 1; i++) buf->text[i] = buf->text[i+1];
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
107
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
108 buf->text[buf->lines-1] = NULL;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
109 buf->lines--;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
110 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
111 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
112
32520
5e062dc4a04d Add code to allow selecting the Close Captioning channel.
reimar
parents: 32513
diff changeset
113 static int channel;
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
114
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
115 void subcc_init(void)
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
116 {
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
117 int i;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
118 //printf("subcc_init(): initing...\n");
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
119 build_char_table();
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
120 for(i=0;i<SUB_MAX_TEXT;i++) {buf1.text[i]=buf2.text[i]=NULL;}
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
121 buf1.lines=buf2.lines=0;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
122 fb=&buf1;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
123 bb=&buf2;
32520
5e062dc4a04d Add code to allow selecting the Close Captioning channel.
reimar
parents: 32513
diff changeset
124 channel = -1;
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
125
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
126 initialized=1;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
127 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
128
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
129
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
130 static void display_buffer(subtitle *buf)
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
131 {
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
132 vo_sub = buf;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
133 vo_osd_changed(OSDTYPE_SUBTITLE);
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
134 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
135
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
136
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
137 static void append_char(char c)
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
138 {
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
139 if(!bb->lines) {bb->lines++; cursor_pos=0;}
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
140 if(bb->text[bb->lines - 1]==NULL)
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
141 {
32513
a150a1bc458d Use calloc instead of malloc+memset.
reimar
parents: 32512
diff changeset
142 bb->text[bb->lines - 1] = calloc(1, CC_MAX_LINE_LENGTH);
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
143 cursor_pos=0;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
144 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
145
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
146 if(c=='\n')
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
147 {
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
148 if(cursor_pos>0 && bb->lines < SUB_MAX_TEXT)
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
149 {
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
150 bb->lines++;cursor_pos=0;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
151 if(cc_mode==CC_ROLLUP){ //Carriage return - scroll buffer one line up
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
152 bb->text[bb->lines - 1]=calloc(1, CC_MAX_LINE_LENGTH);
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
153 scroll_buffer(bb);
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
154 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
155 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
156 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
157 else
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
158 {
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
159 if(cursor_pos==CC_MAX_LINE_LENGTH-1)
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
160 {
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
161 fprintf(stderr,"CC: append_char() reached CC_MAX_LINE_LENGTH!\n");
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
162 return;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
163 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
164 bb->text[bb->lines - 1][cursor_pos++]=c;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
165 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
166 //In CC roll-up mode data should be shown immediately
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
167 if(cc_mode==CC_ROLLUP) display_buffer(bb);
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
168 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
169
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
170
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
171 static void swap_buffers(void)
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
172 {
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
173 subtitle *foo;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
174 foo=fb;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
175 fb=bb;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
176 bb=foo;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
177 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
178
32520
5e062dc4a04d Add code to allow selecting the Close Captioning channel.
reimar
parents: 32513
diff changeset
179 static int selected_channel(void)
5e062dc4a04d Add code to allow selecting the Close Captioning channel.
reimar
parents: 32513
diff changeset
180 {
5e062dc4a04d Add code to allow selecting the Close Captioning channel.
reimar
parents: 32513
diff changeset
181 return subcc_enabled - 1;
5e062dc4a04d Add code to allow selecting the Close Captioning channel.
reimar
parents: 32513
diff changeset
182 }
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
183
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
184 static void cc_decode_EIA608(unsigned short int data)
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
185 {
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
186
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
187 static unsigned short int lastcode=0x0000;
32566
da2dc11d8436 Use uint8_t type instead of unsigned char.
reimar
parents: 32565
diff changeset
188 uint8_t c1 = data & 0x7f;
da2dc11d8436 Use uint8_t type instead of unsigned char.
reimar
parents: 32565
diff changeset
189 uint8_t c2 = (data >> 8) & 0x7f;
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
190
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
191 if (c1 & 0x60) { /* normal character, 0x20 <= c1 <= 0x7f */
32520
5e062dc4a04d Add code to allow selecting the Close Captioning channel.
reimar
parents: 32513
diff changeset
192 if (channel != (selected_channel() & 1))
5e062dc4a04d Add code to allow selecting the Close Captioning channel.
reimar
parents: 32513
diff changeset
193 return;
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
194 append_char(chartbl[c1]);
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
195 if(c2 & 0x60) /*c2 might not be a normal char even if c1 is*/
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
196 append_char(chartbl[c2]);
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
197 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
198 else if (c1 & 0x10) // control code / special char
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
199 {
32520
5e062dc4a04d Add code to allow selecting the Close Captioning channel.
reimar
parents: 32513
diff changeset
200 channel = (c1 & 0x08) >> 3;
5e062dc4a04d Add code to allow selecting the Close Captioning channel.
reimar
parents: 32513
diff changeset
201 if (channel != (selected_channel() & 1))
5e062dc4a04d Add code to allow selecting the Close Captioning channel.
reimar
parents: 32513
diff changeset
202 return;
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
203 c1&=~0x08;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
204 if(data!=lastcode)
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
205 {
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
206 if(c2 & 0x40) { /*PAC, Preamble Address Code */
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
207 append_char('\n'); /*FIXME properly interpret PACs*/
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
208 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
209 else
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
210 switch(c1)
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
211 {
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
212 case 0x10: break; // ext attribute
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
213 case 0x11:
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
214 if((c2 & 0x30)==0x30)
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
215 {
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
216 //printf("[debug]:Special char (ignored)\n");
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
217 /*cc_decode_special_char()*/;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
218 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
219 else if (c2 & 0x20)
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
220 {
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
221 //printf("[debug]: midrow_attr (ignored)\n");
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
222 /*cc_decode_midrow_attr()*/;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
223 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
224 break;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
225 case 0x14:
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
226 switch(c2)
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
227 {
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
228 case 0x00: //CC roll-on mode
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
229 cc_mode=CC_ROLLON;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
230 break;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
231 case 0x25: //CC roll-up, 2 rows
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
232 case 0x26: //CC roll-up, 3 rows
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
233 case 0x27: //CC roll-up, 4 rows
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
234 cc_lines=c2-0x23;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
235 cc_mode=CC_ROLLUP;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
236 break;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
237 case 0x2C: display_buffer(NULL); //EDM
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
238 clear_buffer(fb); break;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
239 case 0x2d: append_char('\n'); //carriage return
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
240 break;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
241 case 0x2e: clear_buffer(bb); //ENM
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
242 break;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
243 case 0x2f: swap_buffers(); //Swap buffers
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
244 display_buffer(fb);
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
245 clear_buffer(bb);
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
246 break;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
247 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
248 break;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
249 case 0x17:
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
250 if( c2>=0x21 && c2<=0x23) //TAB
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
251 {
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
252 break;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
253 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
254 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
255 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
256 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
257 lastcode=data;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
258 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
259
32566
da2dc11d8436 Use uint8_t type instead of unsigned char.
reimar
parents: 32565
diff changeset
260 static void subcc_decode(const uint8_t *inputbuffer, unsigned int inputlength)
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
261 {
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
262 /* The first number may denote a channel number. I don't have the
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
263 * EIA-708 standard, so it is hard to say.
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
264 * From what I could figure out so far, the general format seems to be:
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
265 *
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
266 * repeat
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
267 *
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
268 * 0xfe starts 2 byte sequence of unknown purpose. It might denote
32522
796cd767b024 Fix one -subcc sample.
reimar
parents: 32520
diff changeset
269 * field #2 in line 21 of the VBI.
796cd767b024 Fix one -subcc sample.
reimar
parents: 32520
diff changeset
270 * Treating it identical of 0xff fixes
796cd767b024 Fix one -subcc sample.
reimar
parents: 32520
diff changeset
271 * http://samples.mplayerhq.hu/MPEG-VOB/ClosedCaptions/Starship_Troopers.vob
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
272 *
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
273 * 0xff starts 2 byte EIA-608 sequence, field #1 in line 21 of the VBI.
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
274 * Followed by a 3-code triplet that starts either with 0xff or
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
275 * 0xfe. In either case, the following triplet needs to be ignored
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
276 * for line 21, field 1.
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
277 *
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
278 * 0x00 is padding, followed by 2 more 0x00.
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
279 *
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
280 * 0x01 always seems to appear at the beginning, always seems to
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
281 * be followed by 0xf8, 8-bit number.
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
282 * The lower 7 bits of this 8-bit number seem to denote the
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
283 * number of code triplets that follow.
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
284 * The most significant bit denotes whether the Line 21 field 1
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
285 * captioning information is at odd or even triplet offsets from this
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
286 * beginning triplet. 1 denotes odd offsets, 0 denotes even offsets.
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
287 *
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
288 * Most captions are encoded with odd offsets, so this is what we
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
289 * will assume.
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
290 *
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
291 * until end of packet
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
292 */
32566
da2dc11d8436 Use uint8_t type instead of unsigned char.
reimar
parents: 32565
diff changeset
293 const uint8_t *current = inputbuffer;
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
294 unsigned int curbytes = 0;
32566
da2dc11d8436 Use uint8_t type instead of unsigned char.
reimar
parents: 32565
diff changeset
295 uint8_t data1, data2;
da2dc11d8436 Use uint8_t type instead of unsigned char.
reimar
parents: 32565
diff changeset
296 uint8_t cc_code;
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
297 int odd_offset = 1;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
298
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
299 while (curbytes < inputlength) {
32512
024358659ebd Avoid unnecessary ().
reimar
parents: 32511
diff changeset
300 cc_code = current[0];
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
301
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
302 if (inputlength - curbytes < 2) {
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
303 #ifdef LOG_DEBUG
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
304 fprintf(stderr, "Not enough data for 2-byte CC encoding\n");
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
305 #endif
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
306 break;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
307 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
308
32512
024358659ebd Avoid unnecessary ().
reimar
parents: 32511
diff changeset
309 data1 = current[1];
024358659ebd Avoid unnecessary ().
reimar
parents: 32511
diff changeset
310 data2 = current[2];
32520
5e062dc4a04d Add code to allow selecting the Close Captioning channel.
reimar
parents: 32513
diff changeset
311 current += 3; curbytes += 3;
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
312
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
313 switch (cc_code) {
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
314 case 0xfe:
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
315 case 0xff:
32520
5e062dc4a04d Add code to allow selecting the Close Captioning channel.
reimar
parents: 32513
diff changeset
316 odd_offset ^= 1;
5e062dc4a04d Add code to allow selecting the Close Captioning channel.
reimar
parents: 32513
diff changeset
317 if (odd_offset != selected_channel() >> 1)
5e062dc4a04d Add code to allow selecting the Close Captioning channel.
reimar
parents: 32513
diff changeset
318 break;
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
319 /* expect EIA-608 CC1/CC2 encoding */
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
320 // FIXME check parity!
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
321 // Parity check omitted assuming we are reading from a DVD and therefore
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
322 // we should encounter no "transmission errors".
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
323 cc_decode_EIA608(data1 | (data2 << 8));
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
324 break;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
325
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
326 case 0x00:
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
327 /* This seems to be just padding */
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
328 break;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
329
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
330 case 0x01:
32520
5e062dc4a04d Add code to allow selecting the Close Captioning channel.
reimar
parents: 32513
diff changeset
331 odd_offset = data2 >> 7;
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
332 break;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
333
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
334 default:
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
335 //#ifdef LOG_DEBUG
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
336 fprintf(stderr, "Unknown CC encoding: %x\n", cc_code);
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
337 //#endif
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
338 break;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
339 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
340 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
341 }
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
342
34756
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
343 static const uint8_t mov_cc_signature_1[] = {0, 0, 0, 0xa, 'c', 'd', 'a', 't'};
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
344 static const uint8_t mov_cc_signature_2[] = {0, 0, 0, 0xa, 'c', 'd', 't', '2'};
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
345 /**
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
346 * MOV uses a vastly more verbose representation for EIA 608 CC data than DVDs.
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
347 * This function handles that case.
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
348 */
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
349 static void mov_subcc_decode(const uint8_t *data, unsigned len)
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
350 {
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
351 while (len >= 10) {
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
352 int channel = -1;
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
353 if (memcmp(data, mov_cc_signature_1, sizeof(mov_cc_signature_1)) == 0) {
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
354 channel = 0;
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
355 } else if (memcmp(data, mov_cc_signature_2, sizeof(mov_cc_signature_2)) == 0) {
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
356 channel = 1;
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
357 } else {
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
358 mp_msg(MSGT_OSD, MSGL_V, "Unknown MOV 608 CC formatting\n");
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
359 data++;
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
360 len--;
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
361 continue;
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
362 }
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
363 if (channel == selected_channel() >> 1)
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
364 cc_decode_EIA608(data[8] | (data[9] << 8));
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
365 data += 10;
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
366 len -= 10;
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
367 }
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
368 }
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
369
32566
da2dc11d8436 Use uint8_t type instead of unsigned char.
reimar
parents: 32565
diff changeset
370 void subcc_process_data(const uint8_t *inputdata, unsigned int len)
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
371 {
34756
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
372 int mov_mode = len >= 10 &&
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
373 memcmp(inputdata, mov_cc_signature_1, sizeof(mov_cc_signature_1)) == 0;
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
374 if(!subcc_enabled) return;
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
375 if(!initialized) subcc_init();
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
376
34756
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
377 if (mov_mode) {
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
378 mov_subcc_decode(inputdata, len);
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
379 return;
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
380 }
32458
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
381 subcc_decode(inputdata, len);
ab8fb38f28b1 Move sub_cc.[ch] to the sub directory.
cigaes
parents:
diff changeset
382 }
34756
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
383
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
384 /**
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
385 * This processes CC captions in the format as found in ASTC broadcasts.
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
386 * Like DVD CC it is stored inside the MPEG-frame userdata, but with two
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
387 * differences:
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
388 * 1) It starts with "GA" instead of "CC"
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
389 * 2) It _must_ be reordered in the way the decoder reorders the video frames
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
390 * The latter makes things difficult and is the reason why there is no support
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
391 * for this yet beyond this function.
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
392 */
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
393 void subcc_process_eia708(const uint8_t *data, int len)
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
394 {
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
395 int cc_count;
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
396 if (!subcc_enabled)
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
397 return;
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
398 if (!initialized)
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
399 subcc_init();
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
400 if (len <= 5)
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
401 return;
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
402 if (data[0] != '9' || data[1] != '4' || data[2] != 3) {
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
403 mp_msg(MSGT_OSD, MSGL_ERR, "Unknown ATSC CC type "
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
404 "0x%"PRIx8" 0x%"PRIx8" 0x%"PRIx8"\n",
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
405 data[0], data[1], data[2]);
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
406 return;
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
407 }
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
408 // process_cc_data_flag
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
409 if (!(data[3] & 0x40))
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
410 return;
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
411 cc_count = data[3] & 0x1f;
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
412 data += 5;
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
413 len -= 5;
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
414 cc_count = FFMIN(cc_count, len / 3);
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
415 while (cc_count--) {
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
416 // EAI-608 data
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
417 if ((data[0] & 0xfe) == 0xfc && (data[0] & 1) == selected_channel() >> 1)
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
418 cc_decode_EIA608(data[1] | (data[2] << 8));
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
419 data += 3;
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
420 }
df3ff52039fe Add code to support CC subtitles in ASTC and MOV.
reimar
parents: 34702
diff changeset
421 }