aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx18
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2009-03-14 22:20:49 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:43:28 -0400
commit4ab9b256b5908afbdc030a8c3184ce243f5aca39 (patch)
tree25f604c5794dbae544a6a42c90e4c37ac77082c5 /drivers/media/video/cx18
parent6e1a63720228ef7fc3bd00b04dfb608064fbab4e (diff)
V4L/DVB (11092): cx18: Optimize processing of VBI buffers from the capture unit
Removed some unnecessary memcpy()'s by reworking the compress_*_vbi_buf() functions. Signed-off-by: Andy Walls <awalls@radix.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx18')
-rw-r--r--drivers/media/video/cx18/cx18-vbi.c103
1 files changed, 49 insertions, 54 deletions
diff --git a/drivers/media/video/cx18/cx18-vbi.c b/drivers/media/video/cx18/cx18-vbi.c
index 99f9b2c86b0c..c2aef4add31d 100644
--- a/drivers/media/video/cx18/cx18-vbi.c
+++ b/drivers/media/video/cx18/cx18-vbi.c
@@ -105,54 +105,72 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
105 105
106/* Compress raw VBI format, removes leading SAV codes and surplus space 106/* Compress raw VBI format, removes leading SAV codes and surplus space
107 after the frame. Returns new compressed size. */ 107 after the frame. Returns new compressed size. */
108static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size) 108static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size, u32 hdr_size)
109{ 109{
110 u32 line_size = vbi_active_samples; 110 u32 line_size = vbi_active_samples;
111 u32 lines = cx->vbi.count * 2; 111 u32 lines = cx->vbi.count * 2;
112 u8 sav1 = raw_vbi_sav_rp[0];
113 u8 sav2 = raw_vbi_sav_rp[1];
114 u8 *q = buf; 112 u8 *q = buf;
115 u8 *p; 113 u8 *p;
116 int i; 114 int i;
117 115
116 /* Skip the header */
117 buf += hdr_size;
118
118 for (i = 0; i < lines; i++) { 119 for (i = 0; i < lines; i++) {
119 p = buf + i * line_size; 120 p = buf + i * line_size;
120 121
121 /* Look for SAV code */ 122 /* Look for SAV code */
122 if (p[0] != 0xff || p[1] || p[2] || 123 if (p[0] != 0xff || p[1] || p[2] ||
123 (p[3] != sav1 && p[3] != sav2)) 124 (p[3] != raw_vbi_sav_rp[0] &&
125 p[3] != raw_vbi_sav_rp[1]))
124 break; 126 break;
125 memcpy(q, p + 4, line_size - 4); 127 if (i == lines - 1) {
126 q += line_size - 4; 128 /* last line is hdr_size bytes short - extrapolate it */
129 memcpy(q, p + 4, line_size - 4 - hdr_size);
130 q += line_size - 4 - hdr_size;
131 p += line_size - hdr_size - 1;
132 memset(q, (int) *p, hdr_size);
133 } else {
134 memcpy(q, p + 4, line_size - 4);
135 q += line_size - 4;
136 }
127 } 137 }
128 return lines * (line_size - 4); 138 return lines * (line_size - 4);
129} 139}
130 140
131 141static u32 compress_sliced_buf(struct cx18 *cx, u8 *buf, u32 size,
132/* Compressed VBI format, all found sliced blocks put next to one another 142 const u32 hdr_size)
133 Returns new compressed size */
134static u32 compress_sliced_buf(struct cx18 *cx, u32 line, u8 *buf,
135 u32 size, u8 eav)
136{ 143{
137 struct v4l2_decode_vbi_line vbi; 144 struct v4l2_decode_vbi_line vbi;
138 int i; 145 int i;
146 u32 line = 0;
139 u32 line_size = cx->is_60hz ? vbi_hblank_samples_60Hz 147 u32 line_size = cx->is_60hz ? vbi_hblank_samples_60Hz
140 : vbi_hblank_samples_50Hz; 148 : vbi_hblank_samples_50Hz;
141 149
142 /* find the first valid line */ 150 /* find the first valid line */
143 for (i = 0; i < size; i++, buf++) { 151 for (i = hdr_size, buf += hdr_size; i < size; i++, buf++) {
144 if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == eav) 152 if (buf[0] == 0xff && !buf[1] && !buf[2] &&
153 (buf[3] == sliced_vbi_eav_rp[0] ||
154 buf[3] == sliced_vbi_eav_rp[1]))
145 break; 155 break;
146 } 156 }
147 157
148 size -= i; 158 /*
159 * The last line is short by hdr_size bytes, but for the remaining
160 * checks against size, we pretend that it is not, by counting the
161 * header bytes we knowingly skipped
162 */
163 size -= (i - hdr_size);
149 if (size < line_size) 164 if (size < line_size)
150 return line; 165 return line;
166
151 for (i = 0; i < size / line_size; i++) { 167 for (i = 0; i < size / line_size; i++) {
152 u8 *p = buf + i * line_size; 168 u8 *p = buf + i * line_size;
153 169
154 /* Look for EAV code */ 170 /* Look for EAV code */
155 if (p[0] != 0xff || p[1] || p[2] || p[3] != eav) 171 if (p[0] != 0xff || p[1] || p[2] ||
172 (p[3] != sliced_vbi_eav_rp[0] &&
173 p[3] != sliced_vbi_eav_rp[1]))
156 continue; 174 continue;
157 vbi.p = p + 4; 175 vbi.p = p + 4;
158 v4l2_subdev_call(cx->sd_av, video, decode_vbi_line, &vbi); 176 v4l2_subdev_call(cx->sd_av, video, decode_vbi_line, &vbi);
@@ -170,8 +188,17 @@ static u32 compress_sliced_buf(struct cx18 *cx, u32 line, u8 *buf,
170void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, 188void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
171 int streamtype) 189 int streamtype)
172{ 190{
191 /*
192 * The CX23418 provides a 12 byte header in its raw VBI buffers to us:
193 * 0x3fffffff [4 bytes of something] [4 byte presentation time stamp]
194 */
195 struct vbi_data_hdr {
196 __be32 magic;
197 __be32 unknown;
198 __be32 pts;
199 } *hdr = (struct vbi_data_hdr *) buf->buf;
200
173 u8 *p = (u8 *) buf->buf; 201 u8 *p = (u8 *) buf->buf;
174 __be32 *q = (__be32 *) buf->buf;
175 u32 size = buf->bytesused; 202 u32 size = buf->bytesused;
176 u32 pts; 203 u32 pts;
177 int lines; 204 int lines;
@@ -182,32 +209,15 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
182 /* 209 /*
183 * The CX23418 sends us data that is 32 bit little-endian swapped, 210 * The CX23418 sends us data that is 32 bit little-endian swapped,
184 * but we want the raw VBI bytes in the order they were in the raster 211 * but we want the raw VBI bytes in the order they were in the raster
185 * line. This has a side effect of making the 12 byte header big endian 212 * line. This has a side effect of making the header big endian
186 */ 213 */
187 cx18_buf_swap(buf); 214 cx18_buf_swap(buf);
188 215
189 /*
190 * The CX23418 provides a 12 byte header in it's raw VBI buffers to us:
191 * 0x3fffffff [4 bytes of something] [4 byte presentation time stamp?]
192 */
193
194 /* Raw VBI data */ 216 /* Raw VBI data */
195 if (cx18_raw_vbi(cx)) { 217 if (cx18_raw_vbi(cx)) {
196 u8 type;
197
198 /*
199 * We've set up to get a frame's worth of VBI data at a time.
200 * Skip 12 bytes of header prefixing the first field.
201 */
202 size -= 12;
203 memcpy(p, &buf->buf[12], size);
204 type = p[3];
205 218
206 /* Extrapolate the last 12 bytes of the frame's last line */ 219 size = buf->bytesused =
207 memset(&p[size], (int) p[size - 1], 12); 220 compress_raw_buf(cx, p, size, sizeof(struct vbi_data_hdr));
208 size += 12;
209
210 size = buf->bytesused = compress_raw_buf(cx, p, size);
211 221
212 /* 222 /*
213 * Hack needed for compatibility with old VBI software. 223 * Hack needed for compatibility with old VBI software.
@@ -221,26 +231,11 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
221 231
222 /* Sliced VBI data with data insertion */ 232 /* Sliced VBI data with data insertion */
223 233
224 pts = (be32_to_cpu(q[0]) == 0x3fffffff) ? be32_to_cpu(q[2]) : 0; 234 pts = (be32_to_cpu(hdr->magic) == 0x3fffffff) ? be32_to_cpu(hdr->pts)
235 : 0;
225 236
226 /* 237 lines = compress_sliced_buf(cx, p, size, sizeof(struct vbi_data_hdr));
227 * For calls to compress_sliced_buf(), ensure there are an integral
228 * number of lines by shifting the real data up over the 12 bytes header
229 * that got stuffed in.
230 * FIXME - there's a smarter way to do this with pointers, but for some
231 * reason I can't get it to work correctly right now.
232 */
233 memcpy(p, &buf->buf[12], size-12);
234 238
235 /* first field */
236 lines = compress_sliced_buf(cx, 0, p, size / 2, sliced_vbi_eav_rp[0]);
237 /*
238 * second field
239 * In case the second half does not always begin at the exact address,
240 * start a bit earlier (hence 32).
241 */
242 lines = compress_sliced_buf(cx, lines, p + size / 2 - 32,
243 size / 2 + 32, sliced_vbi_eav_rp[1]);
244 /* always return at least one empty line */ 239 /* always return at least one empty line */
245 if (lines == 0) { 240 if (lines == 0) {
246 cx->vbi.sliced_data[0].id = 0; 241 cx->vbi.sliced_data[0].id = 0;