annotate dvbsubdec.c @ 2918:13dcd22f0816 libavcodec

Add DTS_INC to the CFLAGS for DTS. This is only set by external configure programs (such as the MPlayer one) and thus somewhat hackish. We already do this for things like MLIB_INC and IPP_INC so it should be acceptable.
author diego
date Sun, 23 Oct 2005 18:16:53 +0000
parents 1f117208d20f
children ef2149182f1c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2796
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1 /*
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
2 * DVB subtitle decoding for ffmpeg
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
3 * Copyright (c) 2005 Ian Caulfield.
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
4 *
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
5 * This library is free software; you can redistribute it and/or
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
6 * modify it under the terms of the GNU Lesser General Public
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
7 * License as published by the Free Software Foundation; either
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
8 * version 2 of the License, or (at your option) any later version.
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
9 *
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
10 * This library is distributed in the hope that it will be useful,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
13 * Lesser General Public License for more details.
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
14 *
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
15 * You should have received a copy of the GNU Lesser General Public
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
16 * License along with this library; if not, write to the Free Software
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
18 */
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
19 #include "avcodec.h"
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
20 #include "dsputil.h"
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
21 #include "bitstream.h"
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
22
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
23 //#define DEBUG
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
24 //#define DEBUG_PACKET_CONTENTS
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
25 //#define DEBUG_SAVE_IMAGES
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
26
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
27 #define DVBSUB_PAGE_SEGMENT 0x10
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
28 #define DVBSUB_REGION_SEGMENT 0x11
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
29 #define DVBSUB_CLUT_SEGMENT 0x12
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
30 #define DVBSUB_OBJECT_SEGMENT 0x13
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
31 #define DVBSUB_DISPLAY_SEGMENT 0x80
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
32
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
33 static unsigned char *cm;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
34
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
35 #ifdef DEBUG_SAVE_IMAGES
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
36 #undef fprintf
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
37 #if 0
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
38 static void png_save(const char *filename, uint8_t *bitmap, int w, int h,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
39 uint32_t *rgba_palette)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
40 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
41 int x, y, v;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
42 FILE *f;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
43 char fname[40], fname2[40];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
44 char command[1024];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
45
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
46 snprintf(fname, 40, "%s.ppm", filename);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
47
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
48 f = fopen(fname, "w");
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
49 if (!f) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
50 perror(fname);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
51 exit(1);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
52 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
53 fprintf(f, "P6\n"
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
54 "%d %d\n"
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
55 "%d\n",
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
56 w, h, 255);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
57 for(y = 0; y < h; y++) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
58 for(x = 0; x < w; x++) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
59 v = rgba_palette[bitmap[y * w + x]];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
60 putc((v >> 16) & 0xff, f);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
61 putc((v >> 8) & 0xff, f);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
62 putc((v >> 0) & 0xff, f);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
63 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
64 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
65 fclose(f);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
66
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
67
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
68 snprintf(fname2, 40, "%s-a.pgm", filename);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
69
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
70 f = fopen(fname2, "w");
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
71 if (!f) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
72 perror(fname2);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
73 exit(1);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
74 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
75 fprintf(f, "P5\n"
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
76 "%d %d\n"
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
77 "%d\n",
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
78 w, h, 255);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
79 for(y = 0; y < h; y++) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
80 for(x = 0; x < w; x++) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
81 v = rgba_palette[bitmap[y * w + x]];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
82 putc((v >> 24) & 0xff, f);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
83 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
84 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
85 fclose(f);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
86
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
87 snprintf(command, 1024, "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
88 system(command);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
89
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
90 snprintf(command, 1024, "rm %s %s", fname, fname2);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
91 system(command);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
92 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
93 #endif
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
94
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
95 static void png_save2(const char *filename, uint32_t *bitmap, int w, int h)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
96 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
97 int x, y, v;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
98 FILE *f;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
99 char fname[40], fname2[40];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
100 char command[1024];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
101
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
102 snprintf(fname, 40, "%s.ppm", filename);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
103
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
104 f = fopen(fname, "w");
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
105 if (!f) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
106 perror(fname);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
107 exit(1);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
108 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
109 fprintf(f, "P6\n"
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
110 "%d %d\n"
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
111 "%d\n",
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
112 w, h, 255);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
113 for(y = 0; y < h; y++) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
114 for(x = 0; x < w; x++) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
115 v = bitmap[y * w + x];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
116 putc((v >> 16) & 0xff, f);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
117 putc((v >> 8) & 0xff, f);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
118 putc((v >> 0) & 0xff, f);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
119 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
120 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
121 fclose(f);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
122
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
123
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
124 snprintf(fname2, 40, "%s-a.pgm", filename);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
125
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
126 f = fopen(fname2, "w");
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
127 if (!f) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
128 perror(fname2);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
129 exit(1);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
130 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
131 fprintf(f, "P5\n"
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
132 "%d %d\n"
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
133 "%d\n",
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
134 w, h, 255);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
135 for(y = 0; y < h; y++) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
136 for(x = 0; x < w; x++) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
137 v = bitmap[y * w + x];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
138 putc((v >> 24) & 0xff, f);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
139 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
140 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
141 fclose(f);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
142
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
143 snprintf(command, 1024, "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
144 system(command);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
145
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
146 snprintf(command, 1024, "rm %s %s", fname, fname2);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
147 system(command);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
148 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
149 #endif
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
150
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
151 #define RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
152
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
153 typedef struct DVBSubCLUT {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
154 int id;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
155
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
156 uint32_t clut4[4];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
157 uint32_t clut16[16];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
158 uint32_t clut256[256];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
159
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
160 struct DVBSubCLUT *next;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
161 } DVBSubCLUT;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
162
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
163 static DVBSubCLUT default_clut;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
164
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
165 typedef struct DVBSubObjectDisplay {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
166 int object_id;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
167 int region_id;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
168
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
169 int x_pos;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
170 int y_pos;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
171
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
172 int fgcolour;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
173 int bgcolour;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
174
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
175 struct DVBSubObjectDisplay *region_list_next;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
176 struct DVBSubObjectDisplay *object_list_next;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
177 } DVBSubObjectDisplay;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
178
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
179 typedef struct DVBSubObject {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
180 int id;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
181
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
182 int type;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
183
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
184 DVBSubObjectDisplay *display_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
185
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
186 struct DVBSubObject *next;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
187 } DVBSubObject;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
188
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
189 typedef struct DVBSubRegionDisplay {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
190 int region_id;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
191
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
192 int x_pos;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
193 int y_pos;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
194
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
195 struct DVBSubRegionDisplay *next;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
196 } DVBSubRegionDisplay;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
197
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
198 typedef struct DVBSubRegion {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
199 int id;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
200
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
201 int width;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
202 int height;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
203 int depth;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
204
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
205 int clut;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
206 int bgcolour;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
207
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
208 uint8_t *pbuf;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
209 int buf_size;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
210
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
211 DVBSubObjectDisplay *display_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
212
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
213 struct DVBSubRegion *next;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
214 } DVBSubRegion;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
215
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
216 typedef struct DVBSubContext {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
217 int composition_id;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
218 int ancillary_id;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
219
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
220 int time_out;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
221 DVBSubRegion *region_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
222 DVBSubCLUT *clut_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
223 DVBSubObject *object_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
224
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
225 int display_list_size;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
226 DVBSubRegionDisplay *display_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
227 } DVBSubContext;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
228
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
229
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
230 static DVBSubObject* get_object(DVBSubContext *ctx, int object_id)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
231 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
232 DVBSubObject *ptr = ctx->object_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
233
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
234 while (ptr != NULL && ptr->id != object_id) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
235 ptr = ptr->next;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
236 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
237
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
238 return ptr;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
239 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
240
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
241 static DVBSubCLUT* get_clut(DVBSubContext *ctx, int clut_id)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
242 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
243 DVBSubCLUT *ptr = ctx->clut_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
244
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
245 while (ptr != NULL && ptr->id != clut_id) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
246 ptr = ptr->next;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
247 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
248
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
249 return ptr;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
250 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
251
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
252 static DVBSubRegion* get_region(DVBSubContext *ctx, int region_id)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
253 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
254 DVBSubRegion *ptr = ctx->region_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
255
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
256 while (ptr != NULL && ptr->id != region_id) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
257 ptr = ptr->next;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
258 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
259
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
260 return ptr;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
261 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
262
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
263 static void delete_region_display_list(DVBSubContext *ctx, DVBSubRegion *region)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
264 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
265 DVBSubObject *object, *obj2, **obj2_ptr;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
266 DVBSubObjectDisplay *display, *obj_disp, **obj_disp_ptr;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
267
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
268 while (region->display_list != NULL) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
269 display = region->display_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
270
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
271 object = get_object(ctx, display->object_id);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
272
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
273 if (object != NULL) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
274 obj_disp = object->display_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
275 obj_disp_ptr = &object->display_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
276
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
277 while (obj_disp != NULL && obj_disp != display) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
278 obj_disp_ptr = &obj_disp->object_list_next;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
279 obj_disp = obj_disp->object_list_next;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
280 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
281
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
282 if (obj_disp) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
283 *obj_disp_ptr = obj_disp->object_list_next;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
284
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
285 if (object->display_list == NULL) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
286 obj2 = ctx->object_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
287 obj2_ptr = &ctx->object_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
288
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
289 while (obj2 != NULL && obj2 != object) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
290 obj2_ptr = &obj2->next;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
291 obj2 = obj2->next;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
292 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
293
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
294 *obj2_ptr = obj2->next;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
295
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
296 av_free(obj2);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
297 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
298 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
299 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
300
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
301 region->display_list = display->region_list_next;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
302
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
303 av_free(display);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
304 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
305
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
306 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
307
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
308 static void delete_state(DVBSubContext *ctx)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
309 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
310 DVBSubRegion *region;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
311 DVBSubCLUT *clut;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
312
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
313 while (ctx->region_list != NULL)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
314 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
315 region = ctx->region_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
316
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
317 ctx->region_list = region->next;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
318
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
319 delete_region_display_list(ctx, region);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
320 if (region->pbuf != NULL)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
321 av_free(region->pbuf);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
322
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
323 av_free(region);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
324 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
325
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
326 while (ctx->clut_list != NULL)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
327 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
328 clut = ctx->clut_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
329
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
330 ctx->clut_list = clut->next;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
331
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
332 av_free(clut);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
333 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
334
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
335 /* Should already be null */
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
336 if (ctx->object_list != NULL)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
337 av_log(0, AV_LOG_ERROR, "Memory deallocation error!\n");
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
338 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
339
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
340 static int dvbsub_init_decoder(AVCodecContext *avctx)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
341 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
342 int i, r, g, b, a = 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
343 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
344
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
345 cm = cropTbl + MAX_NEG_CROP;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
346
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
347 memset(avctx->priv_data, 0, sizeof(DVBSubContext));
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
348
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
349 ctx->composition_id = avctx->sub_id & 0xffff;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
350 ctx->ancillary_id = avctx->sub_id >> 16;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
351
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
352 default_clut.id = -1;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
353 default_clut.next = NULL;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
354
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
355 default_clut.clut4[0] = RGBA( 0, 0, 0, 0);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
356 default_clut.clut4[1] = RGBA(255, 255, 255, 255);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
357 default_clut.clut4[2] = RGBA( 0, 0, 0, 255);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
358 default_clut.clut4[3] = RGBA(127, 127, 127, 255);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
359
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
360 default_clut.clut16[0] = RGBA( 0, 0, 0, 0);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
361 for (i = 1; i < 16; i++) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
362 if (i < 8) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
363 r = (i & 1) ? 255 : 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
364 g = (i & 2) ? 255 : 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
365 b = (i & 4) ? 255 : 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
366 } else {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
367 r = (i & 1) ? 127 : 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
368 g = (i & 2) ? 127 : 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
369 b = (i & 4) ? 127 : 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
370 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
371 default_clut.clut16[i] = RGBA(r, g, b, 255);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
372 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
373
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
374 default_clut.clut256[0] = RGBA( 0, 0, 0, 0);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
375 for (i = 1; i < 256; i++) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
376 if (i < 8) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
377 r = (i & 1) ? 255 : 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
378 g = (i & 2) ? 255 : 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
379 b = (i & 4) ? 255 : 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
380 a = 63;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
381 } else {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
382 switch (i & 0x88) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
383 case 0x00:
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
384 r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
385 g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
386 b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
387 a = 255;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
388 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
389 case 0x08:
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
390 r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
391 g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
392 b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
393 a = 127;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
394 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
395 case 0x80:
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
396 r = 127 + ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
397 g = 127 + ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
398 b = 127 + ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
399 a = 255;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
400 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
401 case 0x88:
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
402 r = ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
403 g = ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
404 b = ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
405 a = 255;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
406 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
407 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
408 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
409 default_clut.clut256[i] = RGBA(r, g, b, a);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
410 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
411
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
412 return 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
413 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
414
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
415 static int dvbsub_close_decoder(AVCodecContext *avctx)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
416 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
417 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
418 DVBSubRegionDisplay *display;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
419
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
420 delete_state(ctx);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
421
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
422 while (ctx->display_list != NULL)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
423 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
424 display = ctx->display_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
425 ctx->display_list = display->next;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
426
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
427 av_free(display);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
428 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
429
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
430 return 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
431 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
432
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
433 static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
434 uint8_t **srcbuf, int buf_size,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
435 int non_mod, uint8_t *map_table)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
436 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
437 GetBitContext gb;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
438
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
439 int bits;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
440 int run_length;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
441 int pixels_read = 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
442
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
443 init_get_bits(&gb, *srcbuf, buf_size << 8);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
444
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
445 while (get_bits_count(&gb) < (buf_size << 8) && pixels_read < dbuf_len) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
446 bits = get_bits(&gb, 2);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
447
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
448 if (bits != 0) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
449 if (non_mod != 1 || bits != 1) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
450 if (map_table != NULL)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
451 *destbuf++ = map_table[bits];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
452 else
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
453 *destbuf++ = bits;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
454 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
455 pixels_read++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
456 } else {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
457 bits = get_bits(&gb, 1);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
458 if (bits == 1) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
459 run_length = get_bits(&gb, 3) + 3;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
460 bits = get_bits(&gb, 2);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
461
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
462 if (non_mod == 1 && bits == 1)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
463 pixels_read += run_length;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
464 else {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
465 if (map_table != NULL)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
466 bits = map_table[bits];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
467 while (run_length-- > 0 && pixels_read < dbuf_len) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
468 *destbuf++ = bits;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
469 pixels_read++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
470 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
471 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
472 } else {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
473 bits = get_bits(&gb, 1);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
474 if (bits == 0) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
475 bits = get_bits(&gb, 2);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
476 if (bits == 2) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
477 run_length = get_bits(&gb, 4) + 12;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
478 bits = get_bits(&gb, 2);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
479
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
480 if (non_mod == 1 && bits == 1)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
481 pixels_read += run_length;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
482 else {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
483 if (map_table != NULL)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
484 bits = map_table[bits];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
485 while (run_length-- > 0 && pixels_read < dbuf_len) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
486 *destbuf++ = bits;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
487 pixels_read++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
488 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
489 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
490 } else if (bits == 3) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
491 run_length = get_bits(&gb, 8) + 29;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
492 bits = get_bits(&gb, 2);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
493
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
494 if (non_mod == 1 && bits == 1)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
495 pixels_read += run_length;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
496 else {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
497 if (map_table != NULL)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
498 bits = map_table[bits];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
499 while (run_length-- > 0 && pixels_read < dbuf_len) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
500 *destbuf++ = bits;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
501 pixels_read++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
502 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
503 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
504 } else if (bits == 1) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
505 pixels_read += 2;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
506 if (map_table != NULL)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
507 bits = map_table[0];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
508 else
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
509 bits = 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
510 if (pixels_read <= dbuf_len) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
511 *destbuf++ = bits;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
512 *destbuf++ = bits;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
513 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
514 } else {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
515 (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
516 return pixels_read;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
517 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
518 } else {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
519 if (map_table != NULL)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
520 bits = map_table[0];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
521 else
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
522 bits = 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
523 *destbuf++ = bits;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
524 pixels_read++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
525 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
526 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
527 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
528 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
529
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
530 if (get_bits(&gb, 6) != 0)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
531 av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n");
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
532
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
533 (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
534
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
535 return pixels_read;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
536 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
537
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
538 static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
539 uint8_t **srcbuf, int buf_size,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
540 int non_mod, uint8_t *map_table)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
541 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
542 GetBitContext gb;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
543
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
544 int bits;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
545 int run_length;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
546 int pixels_read = 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
547
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
548 init_get_bits(&gb, *srcbuf, buf_size << 8);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
549
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
550 while (get_bits_count(&gb) < (buf_size << 8) && pixels_read < dbuf_len) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
551 bits = get_bits(&gb, 4);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
552
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
553 if (bits != 0) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
554 if (non_mod != 1 || bits != 1) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
555 if (map_table != NULL)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
556 *destbuf++ = map_table[bits];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
557 else
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
558 *destbuf++ = bits;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
559 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
560 pixels_read++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
561 } else {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
562 bits = get_bits(&gb, 1);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
563 if (bits == 0) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
564 run_length = get_bits(&gb, 3);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
565
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
566 if (run_length == 0) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
567 (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
568 return pixels_read;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
569 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
570
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
571 run_length += 2;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
572
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
573 if (map_table != NULL)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
574 bits = map_table[0];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
575 else
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
576 bits = 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
577
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
578 while (run_length-- > 0 && pixels_read < dbuf_len) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
579 *destbuf++ = bits;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
580 pixels_read++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
581 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
582 } else {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
583 bits = get_bits(&gb, 1);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
584 if (bits == 0) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
585 run_length = get_bits(&gb, 2) + 4;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
586 bits = get_bits(&gb, 4);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
587
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
588 if (non_mod == 1 && bits == 1)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
589 pixels_read += run_length;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
590 else {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
591 if (map_table != NULL)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
592 bits = map_table[bits];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
593 while (run_length-- > 0 && pixels_read < dbuf_len) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
594 *destbuf++ = bits;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
595 pixels_read++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
596 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
597 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
598 } else {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
599 bits = get_bits(&gb, 2);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
600 if (bits == 2) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
601 run_length = get_bits(&gb, 4) + 9;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
602 bits = get_bits(&gb, 4);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
603
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
604 if (non_mod == 1 && bits == 1)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
605 pixels_read += run_length;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
606 else {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
607 if (map_table != NULL)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
608 bits = map_table[bits];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
609 while (run_length-- > 0 && pixels_read < dbuf_len) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
610 *destbuf++ = bits;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
611 pixels_read++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
612 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
613 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
614 } else if (bits == 3) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
615 run_length = get_bits(&gb, 8) + 25;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
616 bits = get_bits(&gb, 4);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
617
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
618 if (non_mod == 1 && bits == 1)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
619 pixels_read += run_length;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
620 else {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
621 if (map_table != NULL)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
622 bits = map_table[bits];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
623 while (run_length-- > 0 && pixels_read < dbuf_len) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
624 *destbuf++ = bits;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
625 pixels_read++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
626 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
627 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
628 } else if (bits == 1) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
629 pixels_read += 2;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
630 if (map_table != NULL)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
631 bits = map_table[0];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
632 else
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
633 bits = 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
634 if (pixels_read <= dbuf_len) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
635 *destbuf++ = bits;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
636 *destbuf++ = bits;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
637 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
638 } else {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
639 if (map_table != NULL)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
640 bits = map_table[0];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
641 else
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
642 bits = 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
643 *destbuf++ = bits;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
644 pixels_read ++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
645 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
646 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
647 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
648 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
649 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
650
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
651 if (get_bits(&gb, 8) != 0)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
652 av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n");
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
653
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
654 (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
655
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
656 return pixels_read;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
657 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
658
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
659 static int dvbsub_read_8bit_string(uint8_t *destbuf, int dbuf_len,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
660 uint8_t **srcbuf, int buf_size,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
661 int non_mod, uint8_t *map_table)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
662 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
663 uint8_t *sbuf_end = (*srcbuf) + buf_size;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
664 int bits;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
665 int run_length;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
666 int pixels_read = 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
667
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
668 while (*srcbuf < sbuf_end && pixels_read < dbuf_len) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
669 bits = *(*srcbuf)++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
670
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
671 if (bits != 0) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
672 if (non_mod != 1 || bits != 1) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
673 if (map_table != NULL)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
674 *destbuf++ = map_table[bits];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
675 else
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
676 *destbuf++ = bits;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
677 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
678 pixels_read++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
679 } else {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
680 bits = *(*srcbuf)++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
681 run_length = bits & 0x7f;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
682 if ((bits & 0x80) == 0) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
683 if (run_length == 0) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
684 return pixels_read;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
685 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
686
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
687 if (map_table != NULL)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
688 bits = map_table[0];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
689 else
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
690 bits = 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
691 while (run_length-- > 0 && pixels_read < dbuf_len) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
692 *destbuf++ = bits;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
693 pixels_read++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
694 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
695 } else {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
696 bits = *(*srcbuf)++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
697
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
698 if (non_mod == 1 && bits == 1)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
699 pixels_read += run_length;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
700 if (map_table != NULL)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
701 bits = map_table[bits];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
702 else while (run_length-- > 0 && pixels_read < dbuf_len) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
703 *destbuf++ = bits;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
704 pixels_read++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
705 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
706 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
707 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
708 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
709
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
710 if (*(*srcbuf)++ != 0)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
711 av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n");
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
712
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
713 return pixels_read;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
714 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
715
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
716
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
717
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
718 static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDisplay *display,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
719 uint8_t *buf, int buf_size, int top_bottom, int non_mod)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
720 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
721 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
722
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
723 DVBSubRegion *region = get_region(ctx, display->region_id);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
724 uint8_t *buf_end = buf + buf_size;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
725 uint8_t *pbuf;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
726 int x_pos, y_pos;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
727 int i;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
728
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
729 uint8_t map2to4[] = { 0x0, 0x7, 0x8, 0xf};
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
730 uint8_t map2to8[] = {0x00, 0x77, 0x88, 0xff};
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
731 uint8_t map4to8[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
732 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
733 uint8_t *map_table;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
734
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
735 #ifdef DEBUG
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
736 av_log(avctx, AV_LOG_INFO, "DVB pixel block size %d, %s field:\n", buf_size,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
737 top_bottom ? "bottom" : "top");
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
738 #endif
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
739
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
740 #ifdef DEBUG_PACKET_CONTENTS
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
741 for (i = 0; i < buf_size; i++)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
742 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
743 if (i % 16 == 0)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
744 av_log(avctx, AV_LOG_INFO, "0x%08p: ", buf+i);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
745
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
746 av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
747 if (i % 16 == 15)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
748 av_log(avctx, AV_LOG_INFO, "\n");
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
749 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
750
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
751 if (i % 16 != 0)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
752 av_log(avctx, AV_LOG_INFO, "\n");
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
753
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
754 #endif
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
755
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
756 if (region == 0)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
757 return;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
758
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
759 pbuf = region->pbuf;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
760
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
761 x_pos = display->x_pos;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
762 y_pos = display->y_pos;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
763
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
764 if ((y_pos & 1) != top_bottom)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
765 y_pos++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
766
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
767 while (buf < buf_end) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
768 if (x_pos > region->width || y_pos > region->height) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
769 av_log(avctx, AV_LOG_ERROR, "Invalid object location!\n");
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
770 return;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
771 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
772
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
773 switch (*buf++) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
774 case 0x10:
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
775 if (region->depth == 8)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
776 map_table = map2to8;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
777 else if (region->depth == 4)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
778 map_table = map2to4;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
779 else
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
780 map_table = NULL;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
781
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
782 x_pos += dvbsub_read_2bit_string(pbuf + (y_pos * region->width) + x_pos,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
783 region->width - x_pos, &buf, buf_size,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
784 non_mod, map_table);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
785 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
786 case 0x11:
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
787 if (region->depth < 4) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
788 av_log(avctx, AV_LOG_ERROR, "4-bit pixel string in %d-bit region!\n", region->depth);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
789 return;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
790 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
791
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
792 if (region->depth == 8)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
793 map_table = map4to8;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
794 else
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
795 map_table = NULL;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
796
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
797 x_pos += dvbsub_read_4bit_string(pbuf + (y_pos * region->width) + x_pos,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
798 region->width - x_pos, &buf, buf_size,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
799 non_mod, map_table);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
800 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
801 case 0x12:
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
802 if (region->depth < 8) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
803 av_log(avctx, AV_LOG_ERROR, "8-bit pixel string in %d-bit region!\n", region->depth);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
804 return;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
805 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
806
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
807 x_pos += dvbsub_read_8bit_string(pbuf + (y_pos * region->width) + x_pos,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
808 region->width - x_pos, &buf, buf_size,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
809 non_mod, NULL);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
810 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
811
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
812 case 0x20:
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
813 map2to4[0] = (*buf) >> 4;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
814 map2to4[1] = (*buf++) & 0xf;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
815 map2to4[2] = (*buf) >> 4;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
816 map2to4[3] = (*buf++) & 0xf;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
817 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
818 case 0x21:
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
819 for (i = 0; i < 4; i++)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
820 map2to8[i] = *buf++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
821 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
822 case 0x22:
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
823 for (i = 0; i < 16; i++)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
824 map4to8[i] = *buf++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
825 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
826
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
827 case 0xf0:
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
828 x_pos = display->x_pos;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
829 y_pos += 2;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
830 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
831 default:
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
832 av_log(avctx, AV_LOG_INFO, "Unknown/unsupported pixel block 0x%x\n", *(buf-1));
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
833 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
834 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
835
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
836 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
837
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
838 static void dvbsub_parse_object_segment(AVCodecContext *avctx,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
839 uint8_t *buf, int buf_size)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
840 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
841 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
842
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
843 uint8_t *buf_end = buf + buf_size;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
844 uint8_t *block;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
845 int object_id;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
846 DVBSubObject *object;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
847 DVBSubObjectDisplay *display;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
848 int top_field_len, bottom_field_len;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
849
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
850 int coding_method, non_modifying_colour;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
851
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
852 object_id = BE_16(buf);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
853 buf += 2;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
854
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
855 object = get_object(ctx, object_id);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
856
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
857 if (!object)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
858 return;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
859
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
860 coding_method = ((*buf) >> 2) & 3;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
861 non_modifying_colour = ((*buf++) >> 1) & 1;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
862
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
863 if (coding_method == 0) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
864 top_field_len = BE_16(buf);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
865 buf += 2;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
866 bottom_field_len = BE_16(buf);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
867 buf += 2;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
868
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
869 if (buf + top_field_len + bottom_field_len > buf_end) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
870 av_log(avctx, AV_LOG_ERROR, "Field data size too large\n");
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
871 return;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
872 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
873
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
874 for (display = object->display_list; display != 0; display = display->object_list_next) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
875 block = buf;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
876
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
877 dvbsub_parse_pixel_data_block(avctx, display, block, top_field_len, 0,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
878 non_modifying_colour);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
879
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
880 if (bottom_field_len > 0)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
881 block = buf + top_field_len;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
882 else
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
883 bottom_field_len = top_field_len;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
884
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
885 dvbsub_parse_pixel_data_block(avctx, display, block, bottom_field_len, 1,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
886 non_modifying_colour);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
887 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
888
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
889 /* } else if (coding_method == 1) {*/
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
890
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
891 } else {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
892 av_log(avctx, AV_LOG_ERROR, "Unknown object coding %d\n", coding_method);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
893 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
894
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
895 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
896
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
897 #define SCALEBITS 10
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
898 #define ONE_HALF (1 << (SCALEBITS - 1))
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
899 #define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5))
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
900
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
901 #define YUV_TO_RGB1_CCIR(cb1, cr1)\
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
902 {\
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
903 cb = (cb1) - 128;\
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
904 cr = (cr1) - 128;\
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
905 r_add = FIX(1.40200*255.0/224.0) * cr + ONE_HALF;\
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
906 g_add = - FIX(0.34414*255.0/224.0) * cb - FIX(0.71414*255.0/224.0) * cr + \
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
907 ONE_HALF;\
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
908 b_add = FIX(1.77200*255.0/224.0) * cb + ONE_HALF;\
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
909 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
910
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
911 #define YUV_TO_RGB2_CCIR(r, g, b, y1)\
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
912 {\
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
913 y = ((y1) - 16) * FIX(255.0/219.0);\
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
914 r = cm[(y + r_add) >> SCALEBITS];\
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
915 g = cm[(y + g_add) >> SCALEBITS];\
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
916 b = cm[(y + b_add) >> SCALEBITS];\
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
917 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
918
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
919
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
920 static void dvbsub_parse_clut_segment(AVCodecContext *avctx,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
921 uint8_t *buf, int buf_size)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
922 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
923 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
924
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
925 uint8_t *buf_end = buf + buf_size;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
926 int clut_id;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
927 DVBSubCLUT *clut;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
928 int entry_id, depth , full_range;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
929 int y, cr, cb, alpha;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
930 int r, g, b, r_add, g_add, b_add;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
931
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
932 #ifdef DEBUG_PACKET_CONTENTS
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
933 int i;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
934
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
935 av_log(avctx, AV_LOG_INFO, "DVB clut packet:\n");
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
936
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
937 for (i=0; i < buf_size; i++)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
938 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
939 av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
940 if (i % 16 == 15)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
941 av_log(avctx, AV_LOG_INFO, "\n");
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
942 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
943
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
944 if (i % 16 != 0)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
945 av_log(avctx, AV_LOG_INFO, "\n");
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
946
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
947 #endif
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
948
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
949 clut_id = *buf++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
950 buf += 1;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
951
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
952 clut = get_clut(ctx, clut_id);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
953
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
954 if (clut == NULL) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
955 clut = av_malloc(sizeof(DVBSubCLUT));
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
956
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
957 memcpy(clut, &default_clut, sizeof(DVBSubCLUT));
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
958
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
959 clut->id = clut_id;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
960
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
961 clut->next = ctx->clut_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
962 ctx->clut_list = clut;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
963 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
964
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
965 while (buf + 4 < buf_end)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
966 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
967 entry_id = *buf++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
968
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
969 depth = (*buf) & 0xe0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
970
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
971 if (depth == 0) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
972 av_log(avctx, AV_LOG_ERROR, "Invalid clut depth 0x%x!\n", *buf);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
973 return;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
974 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
975
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
976 full_range = (*buf++) & 1;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
977
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
978 if (full_range) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
979 y = *buf++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
980 cr = *buf++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
981 cb = *buf++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
982 alpha = *buf++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
983 } else {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
984 y = buf[0] & 0xfc;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
985 cr = (((buf[0] & 3) << 2) | ((buf[1] >> 6) & 3)) << 4;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
986 cb = (buf[1] << 2) & 0xf0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
987 alpha = (buf[1] << 6) & 0xc0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
988
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
989 buf += 2;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
990 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
991
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
992 if (y == 0)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
993 alpha = 0xff;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
994
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
995 YUV_TO_RGB1_CCIR(cb, cr);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
996 YUV_TO_RGB2_CCIR(r, g, b, y);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
997
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
998 #ifdef DEBUG
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
999 av_log(avctx, AV_LOG_INFO, "clut %d := (%d,%d,%d,%d)\n", entry_id, r, g, b, alpha);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1000 #endif
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1001
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1002 if (depth & 0x80)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1003 clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1004 if (depth & 0x40)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1005 clut->clut16[entry_id] = RGBA(r,g,b,255 - alpha);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1006 if (depth & 0x20)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1007 clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1008 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1009 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1010
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1011
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1012 static void dvbsub_parse_region_segment(AVCodecContext *avctx,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1013 uint8_t *buf, int buf_size)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1014 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1015 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1016
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1017 uint8_t *buf_end = buf + buf_size;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1018 int region_id, object_id;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1019 DVBSubRegion *region;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1020 DVBSubObject *object;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1021 DVBSubObjectDisplay *display;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1022 int fill;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1023
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1024 if (buf_size < 10)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1025 return;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1026
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1027 region_id = *buf++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1028
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1029 region = get_region(ctx, region_id);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1030
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1031 if (region == NULL)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1032 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1033 region = av_mallocz(sizeof(DVBSubRegion));
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1034
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1035 region->id = region_id;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1036
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1037 region->next = ctx->region_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1038 ctx->region_list = region;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1039 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1040
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1041 fill = ((*buf++) >> 3) & 1;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1042
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1043 region->width = BE_16(buf);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1044 buf += 2;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1045 region->height = BE_16(buf);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1046 buf += 2;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1047
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1048 if (region->width * region->height != region->buf_size) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1049 if (region->pbuf != 0)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1050 av_free(region->pbuf);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1051
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1052 region->buf_size = region->width * region->height;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1053
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1054 region->pbuf = av_malloc(region->buf_size);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1055
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1056 fill = 1;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1057 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1058
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1059 region->depth = 1 << (((*buf++) >> 2) & 7);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1060 region->clut = *buf++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1061
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1062 if (region->depth == 8)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1063 region->bgcolour = *buf++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1064 else {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1065 buf += 1;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1066
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1067 if (region->depth == 4)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1068 region->bgcolour = (((*buf++) >> 4) & 15);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1069 else
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1070 region->bgcolour = (((*buf++) >> 2) & 3);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1071 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1072
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1073 #ifdef DEBUG
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1074 av_log(avctx, AV_LOG_INFO, "Region %d, (%dx%d)\n", region_id, region->width, region->height);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1075 #endif
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1076
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1077 if (fill) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1078 memset(region->pbuf, region->bgcolour, region->buf_size);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1079 #ifdef DEBUG
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1080 av_log(avctx, AV_LOG_INFO, "Fill region (%d)\n", region->bgcolour);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1081 #endif
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1082 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1083
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1084 delete_region_display_list(ctx, region);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1085
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1086 while (buf + 5 < buf_end) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1087 object_id = BE_16(buf);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1088 buf += 2;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1089
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1090 object = get_object(ctx, object_id);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1091
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1092 if (object == NULL) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1093 object = av_mallocz(sizeof(DVBSubObject));
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1094
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1095 object->id = object_id;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1096 object->next = ctx->object_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1097 ctx->object_list = object;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1098 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1099
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1100 object->type = (*buf) >> 6;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1101
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1102 display = av_mallocz(sizeof(DVBSubObjectDisplay));
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1103
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1104 display->object_id = object_id;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1105 display->region_id = region_id;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1106
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1107 display->x_pos = BE_16(buf) & 0xfff;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1108 buf += 2;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1109 display->y_pos = BE_16(buf) & 0xfff;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1110 buf += 2;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1111
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1112 if ((object->type == 1 || object->type == 2) && buf+1 < buf_end) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1113 display->fgcolour = *buf++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1114 display->bgcolour = *buf++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1115 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1116
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1117 display->region_list_next = region->display_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1118 region->display_list = display;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1119
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1120 display->object_list_next = object->display_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1121 object->display_list = display;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1122 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1123 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1124
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1125 static void dvbsub_parse_page_segment(AVCodecContext *avctx,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1126 uint8_t *buf, int buf_size)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1127 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1128 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1129 DVBSubRegionDisplay *display;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1130 DVBSubRegionDisplay *tmp_display_list, **tmp_ptr;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1131
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1132 uint8_t *buf_end = buf + buf_size;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1133 int region_id;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1134 int page_state;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1135
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1136 if (buf_size < 1)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1137 return;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1138
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1139 ctx->time_out = *buf++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1140 page_state = ((*buf++) >> 2) & 3;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1141
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1142 #ifdef DEBUG
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1143 av_log(avctx, AV_LOG_INFO, "Page time out %ds, state %d\n", ctx->time_out, page_state);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1144 #endif
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1145
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1146 if (page_state == 2)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1147 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1148 delete_state(ctx);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1149 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1150
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1151 tmp_display_list = ctx->display_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1152 ctx->display_list = NULL;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1153 ctx->display_list_size = 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1154
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1155 while (buf + 5 < buf_end) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1156 region_id = *buf++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1157 buf += 1;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1158
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1159 display = tmp_display_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1160 tmp_ptr = &tmp_display_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1161
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1162 while (display != NULL && display->region_id != region_id) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1163 tmp_ptr = &display->next;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1164 display = display->next;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1165 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1166
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1167 if (display == NULL)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1168 display = av_mallocz(sizeof(DVBSubRegionDisplay));
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1169
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1170 display->region_id = region_id;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1171
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1172 display->x_pos = BE_16(buf);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1173 buf += 2;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1174 display->y_pos = BE_16(buf);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1175 buf += 2;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1176
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1177 *tmp_ptr = display->next;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1178
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1179 display->next = ctx->display_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1180 ctx->display_list = display;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1181 ctx->display_list_size++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1182
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1183 #ifdef DEBUG
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1184 av_log(avctx, AV_LOG_INFO, "Region %d, (%d,%d)\n", region_id, display->x_pos, display->y_pos);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1185 #endif
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1186 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1187
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1188 while (tmp_display_list != 0) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1189 display = tmp_display_list;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1190
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1191 tmp_display_list = display->next;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1192
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1193 av_free(display);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1194 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1195
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1196 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1197
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1198
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1199 #ifdef DEBUG_SAVE_IMAGES
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1200 static void save_display_set(DVBSubContext *ctx)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1201 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1202 DVBSubRegion *region;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1203 DVBSubRegionDisplay *display;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1204 DVBSubCLUT *clut;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1205 uint32_t *clut_table;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1206 int x_pos, y_pos, width, height;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1207 int x, y, y_off, x_off;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1208 uint32_t *pbuf;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1209 char filename[32];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1210 static int fileno_index = 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1211
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1212 x_pos = -1;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1213 y_pos = -1;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1214 width = 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1215 height = 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1216
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1217 for (display = ctx->display_list; display != NULL; display = display->next) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1218 region = get_region(ctx, display->region_id);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1219
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1220 if (x_pos == -1) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1221 x_pos = display->x_pos;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1222 y_pos = display->y_pos;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1223 width = region->width;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1224 height = region->height;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1225 } else {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1226 if (display->x_pos < x_pos) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1227 width += (x_pos - display->x_pos);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1228 x_pos = display->x_pos;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1229 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1230
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1231 if (display->y_pos < y_pos) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1232 height += (y_pos - display->y_pos);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1233 y_pos = display->y_pos;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1234 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1235
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1236 if (display->x_pos + region->width > x_pos + width) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1237 width = display->x_pos + region->width - x_pos;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1238 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1239
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1240 if (display->y_pos + region->height > y_pos + height) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1241 height = display->y_pos + region->height - y_pos;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1242 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1243 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1244 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1245
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1246 if (x_pos >= 0) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1247
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1248 pbuf = av_malloc(width * height * 4);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1249
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1250 for (display = ctx->display_list; display != NULL; display = display->next) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1251 region = get_region(ctx, display->region_id);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1252
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1253 x_off = display->x_pos - x_pos;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1254 y_off = display->y_pos - y_pos;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1255
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1256 clut = get_clut(ctx, region->clut);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1257
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1258 if (clut == 0)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1259 clut = &default_clut;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1260
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1261 switch (region->depth) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1262 case 2:
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1263 clut_table = clut->clut4;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1264 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1265 case 8:
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1266 clut_table = clut->clut256;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1267 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1268 case 4:
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1269 default:
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1270 clut_table = clut->clut16;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1271 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1272 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1273
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1274 for (y = 0; y < region->height; y++) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1275 for (x = 0; x < region->width; x++) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1276 pbuf[((y + y_off) * width) + x_off + x] =
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1277 clut_table[region->pbuf[y * region->width + x]];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1278 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1279 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1280
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1281 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1282
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1283 snprintf(filename, 32, "dvbs.%d", fileno_index);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1284
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1285 png_save2(filename, pbuf, width, height);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1286
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1287 av_free(pbuf);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1288 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1289
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1290 fileno_index++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1291 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1292 #endif
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1293
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1294 static int dvbsub_display_end_segment(AVCodecContext *avctx, uint8_t *buf,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1295 int buf_size, AVSubtitle *sub)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1296 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1297 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1298
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1299 DVBSubRegion *region;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1300 DVBSubRegionDisplay *display;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1301 AVSubtitleRect *rect;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1302 DVBSubCLUT *clut;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1303 uint32_t *clut_table;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1304 int i;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1305
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1306 sub->rects = NULL;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1307 sub->start_display_time = 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1308 sub->end_display_time = ctx->time_out * 1000;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1309 sub->format = 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1310
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1311 sub->num_rects = ctx->display_list_size;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1312
2833
1f117208d20f subs.diff fixes a couple of minor bugs in my DVB subtitle decoder, and also fixes a few
michael
parents: 2796
diff changeset
1313 if (sub->num_rects > 0)
1f117208d20f subs.diff fixes a couple of minor bugs in my DVB subtitle decoder, and also fixes a few
michael
parents: 2796
diff changeset
1314 sub->rects = av_mallocz(sizeof(AVSubtitleRect) * sub->num_rects);
2796
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1315
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1316 i = 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1317
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1318 for (display = ctx->display_list; display != NULL; display = display->next) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1319 region = get_region(ctx, display->region_id);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1320 rect = &sub->rects[i];
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1321
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1322 if (region == NULL)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1323 continue;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1324
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1325 rect->x = display->x_pos;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1326 rect->y = display->y_pos;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1327 rect->w = region->width;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1328 rect->h = region->height;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1329 rect->nb_colors = 16;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1330 rect->linesize = region->width;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1331
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1332 clut = get_clut(ctx, region->clut);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1333
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1334 if (clut == NULL)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1335 clut = &default_clut;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1336
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1337 switch (region->depth) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1338 case 2:
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1339 clut_table = clut->clut4;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1340 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1341 case 8:
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1342 clut_table = clut->clut256;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1343 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1344 case 4:
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1345 default:
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1346 clut_table = clut->clut16;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1347 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1348 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1349
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1350 rect->rgba_palette = av_malloc((1 << region->depth) * sizeof(uint32_t));
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1351 memcpy(rect->rgba_palette, clut_table, (1 << region->depth) * sizeof(uint32_t));
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1352
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1353 rect->bitmap = av_malloc(region->buf_size);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1354 memcpy(rect->bitmap, region->pbuf, region->buf_size);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1355
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1356 i++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1357 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1358
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1359 sub->num_rects = i;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1360
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1361 #ifdef DEBUG_SAVE_IMAGES
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1362 save_display_set(ctx);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1363 #endif
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1364
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1365 return 1;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1366 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1367
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1368 static int dvbsub_decode(AVCodecContext *avctx,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1369 void *data, int *data_size,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1370 uint8_t *buf, int buf_size)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1371 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1372 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1373 AVSubtitle *sub = (AVSubtitle*) data;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1374 uint8_t *p, *p_end;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1375 int segment_type;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1376 int page_id;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1377 int segment_length;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1378
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1379 #ifdef DEBUG_PACKET_CONTENTS
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1380 int i;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1381
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1382 av_log(avctx, AV_LOG_INFO, "DVB sub packet:\n");
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1383
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1384 for (i=0; i < buf_size; i++)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1385 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1386 av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1387 if (i % 16 == 15)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1388 av_log(avctx, AV_LOG_INFO, "\n");
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1389 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1390
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1391 if (i % 16 != 0)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1392 av_log(avctx, AV_LOG_INFO, "\n");
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1393
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1394 #endif
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1395
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1396 if (buf_size <= 2)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1397 return -1;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1398
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1399 p = buf;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1400 p_end = buf + buf_size;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1401
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1402 while (p < p_end && *p == 0x0f)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1403 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1404 p += 1;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1405 segment_type = *p++;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1406 page_id = BE_16(p);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1407 p += 2;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1408 segment_length = BE_16(p);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1409 p += 2;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1410
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1411 if (page_id == ctx->composition_id || page_id == ctx->ancillary_id) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1412 switch (segment_type) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1413 case DVBSUB_PAGE_SEGMENT:
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1414 dvbsub_parse_page_segment(avctx, p, segment_length);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1415 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1416 case DVBSUB_REGION_SEGMENT:
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1417 dvbsub_parse_region_segment(avctx, p, segment_length);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1418 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1419 case DVBSUB_CLUT_SEGMENT:
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1420 dvbsub_parse_clut_segment(avctx, p, segment_length);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1421 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1422 case DVBSUB_OBJECT_SEGMENT:
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1423 dvbsub_parse_object_segment(avctx, p, segment_length);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1424 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1425 case DVBSUB_DISPLAY_SEGMENT:
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1426 *data_size = dvbsub_display_end_segment(avctx, p, segment_length, sub);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1427 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1428 default:
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1429 #ifdef DEBUG
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1430 av_log(avctx, AV_LOG_INFO, "Subtitling segment type 0x%x, page id %d, length %d\n",
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1431 segment_type, page_id, segment_length);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1432 #endif
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1433 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1434 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1435 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1436
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1437 p += segment_length;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1438 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1439
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1440 if (p != p_end)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1441 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1442 #ifdef DEBUG
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1443 av_log(avctx, AV_LOG_INFO, "Junk at end of packet\n");
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1444 #endif
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1445 return -1;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1446 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1447
2833
1f117208d20f subs.diff fixes a couple of minor bugs in my DVB subtitle decoder, and also fixes a few
michael
parents: 2796
diff changeset
1448 return buf_size;
2796
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1449 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1450
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1451
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1452 AVCodec dvbsub_decoder = {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1453 "dvbsub",
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1454 CODEC_TYPE_SUBTITLE,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1455 CODEC_ID_DVB_SUBTITLE,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1456 sizeof(DVBSubContext),
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1457 dvbsub_init_decoder,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1458 NULL,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1459 dvbsub_close_decoder,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1460 dvbsub_decode,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1461 };
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1462
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1463 /* Parser (mostly) copied from dvdsub.c */
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1464
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1465 #define PARSE_BUF_SIZE (65536)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1466
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1467
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1468 /* parser definition */
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1469 typedef struct DVBSubParseContext {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1470 uint8_t *packet_buf;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1471 int packet_start;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1472 int packet_index;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1473 int in_packet;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1474 } DVBSubParseContext;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1475
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1476 static int dvbsub_parse_init(AVCodecParserContext *s)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1477 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1478 DVBSubParseContext *pc = s->priv_data;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1479 pc->packet_buf = av_malloc(PARSE_BUF_SIZE);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1480
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1481 return 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1482 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1483
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1484 static int dvbsub_parse(AVCodecParserContext *s,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1485 AVCodecContext *avctx,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1486 uint8_t **poutbuf, int *poutbuf_size,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1487 const uint8_t *buf, int buf_size)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1488 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1489 DVBSubParseContext *pc = s->priv_data;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1490 uint8_t *p, *p_end;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1491 int len, buf_pos = 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1492
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1493 #ifdef DEBUG
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1494 av_log(avctx, AV_LOG_INFO, "DVB parse packet pts=%Lx, lpts=%Lx, cpts=%Lx:\n",
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1495 s->pts, s->last_pts, s->cur_frame_pts[s->cur_frame_start_index]);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1496 #endif
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1497
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1498 #ifdef DEBUG_PACKET_CONTENTS
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1499 int i;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1500
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1501 for (i=0; i < buf_size; i++)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1502 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1503 av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1504 if (i % 16 == 15)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1505 av_log(avctx, AV_LOG_INFO, "\n");
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1506 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1507
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1508 if (i % 16 != 0)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1509 av_log(avctx, AV_LOG_INFO, "\n");
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1510
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1511 #endif
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1512
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1513 *poutbuf = NULL;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1514 *poutbuf_size = 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1515
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1516 s->fetch_timestamp = 1;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1517
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1518 if (s->last_pts != s->pts && s->last_pts != AV_NOPTS_VALUE) /* Start of a new packet */
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1519 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1520 if (pc->packet_index != pc->packet_start)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1521 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1522 #ifdef DEBUG
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1523 av_log(avctx, AV_LOG_INFO, "Discarding %d bytes\n",
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1524 pc->packet_index - pc->packet_start);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1525 #endif
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1526 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1527
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1528 pc->packet_start = 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1529 pc->packet_index = 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1530
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1531 if (buf_size < 2 || buf[0] != 0x20 || buf[1] != 0x00) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1532 #ifdef DEBUG
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1533 av_log(avctx, AV_LOG_INFO, "Bad packet header\n");
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1534 #endif
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1535 return -1;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1536 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1537
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1538 buf_pos = 2;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1539
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1540 pc->in_packet = 1;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1541 } else {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1542 if (pc->packet_start != 0)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1543 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1544 if (pc->packet_index != pc->packet_start)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1545 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1546 memmove(pc->packet_buf, pc->packet_buf + pc->packet_start,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1547 pc->packet_index - pc->packet_start);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1548
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1549 pc->packet_index -= pc->packet_start;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1550 pc->packet_start = 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1551 } else {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1552 pc->packet_start = 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1553 pc->packet_index = 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1554 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1555 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1556 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1557
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1558 if (buf_size - buf_pos + pc->packet_index > PARSE_BUF_SIZE)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1559 return -1;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1560
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1561 /* if not currently in a packet, discard data */
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1562 if (pc->in_packet == 0)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1563 return buf_size;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1564
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1565 memcpy(pc->packet_buf + pc->packet_index, buf + buf_pos, buf_size - buf_pos);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1566 pc->packet_index += buf_size - buf_pos;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1567
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1568 p = pc->packet_buf;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1569 p_end = pc->packet_buf + pc->packet_index;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1570
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1571 while (p < p_end)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1572 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1573 if (*p == 0x0f)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1574 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1575 if (p + 6 <= p_end)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1576 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1577 len = BE_16(p + 4);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1578
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1579 if (p + len + 6 <= p_end)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1580 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1581 *poutbuf_size += len + 6;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1582
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1583 p += len + 6;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1584 } else
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1585 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1586 } else
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1587 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1588 } else if (*p == 0xff) {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1589 if (p + 1 < p_end)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1590 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1591 #ifdef DEBUG
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1592 av_log(avctx, AV_LOG_INFO, "Junk at end of packet\n");
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1593 #endif
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1594 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1595 pc->packet_index = p - pc->packet_buf;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1596 pc->in_packet = 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1597 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1598 } else {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1599 av_log(avctx, AV_LOG_ERROR, "Junk in packet\n");
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1600
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1601 pc->packet_index = p - pc->packet_buf;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1602 pc->in_packet = 0;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1603 break;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1604 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1605 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1606
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1607 if (*poutbuf_size > 0)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1608 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1609 *poutbuf = pc->packet_buf;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1610 pc->packet_start = *poutbuf_size;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1611 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1612
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1613 if (s->last_pts == AV_NOPTS_VALUE)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1614 s->last_pts = s->pts;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1615
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1616 return buf_size;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1617 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1618
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1619 static void dvbsub_parse_close(AVCodecParserContext *s)
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1620 {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1621 DVBSubParseContext *pc = s->priv_data;
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1622 av_freep(&pc->packet_buf);
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1623 }
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1624
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1625 AVCodecParser dvbsub_parser = {
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1626 { CODEC_ID_DVB_SUBTITLE },
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1627 sizeof(DVBSubParseContext),
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1628 dvbsub_parse_init,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1629 dvbsub_parse,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1630 dvbsub_parse_close,
95c35706acbb DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
diff changeset
1631 };