blob: d60cd5ecf821ceefa530459bc220e069abd9f149 [file] [log] [blame]
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001/*
2 * cx2341x - generic code for cx23415/6 based devices
3 *
4 * Copyright (C) 2006 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/errno.h>
25#include <linux/kernel.h>
26#include <linux/init.h>
27#include <linux/types.h>
28#include <linux/videodev2.h>
29#include <linux/i2c.h>
30
31#include <media/tuner.h>
32#include <media/cx2341x.h>
33#include <media/v4l2-common.h>
34
35MODULE_DESCRIPTION("cx23415/6 driver");
36MODULE_AUTHOR("Hans Verkuil");
37MODULE_LICENSE("GPL");
38
39static int debug = 0;
40module_param(debug, int, 0644);
41MODULE_PARM_DESC(debug, "Debug level (0-1)");
42
Hans Verkuilcc7bc642006-06-19 17:53:08 -030043const u32 cx2341x_mpeg_ctrls[] = {
44 V4L2_CID_MPEG_CLASS,
45 V4L2_CID_MPEG_STREAM_TYPE,
Hans Verkuil8cbde942006-06-24 14:36:02 -030046 V4L2_CID_MPEG_STREAM_VBI_FMT,
Hans Verkuilcc7bc642006-06-19 17:53:08 -030047 V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
48 V4L2_CID_MPEG_AUDIO_ENCODING,
49 V4L2_CID_MPEG_AUDIO_L2_BITRATE,
50 V4L2_CID_MPEG_AUDIO_MODE,
51 V4L2_CID_MPEG_AUDIO_MODE_EXTENSION,
52 V4L2_CID_MPEG_AUDIO_EMPHASIS,
53 V4L2_CID_MPEG_AUDIO_CRC,
54 V4L2_CID_MPEG_VIDEO_ENCODING,
55 V4L2_CID_MPEG_VIDEO_ASPECT,
56 V4L2_CID_MPEG_VIDEO_B_FRAMES,
57 V4L2_CID_MPEG_VIDEO_GOP_SIZE,
58 V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
Hans Verkuilcc7bc642006-06-19 17:53:08 -030059 V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
60 V4L2_CID_MPEG_VIDEO_BITRATE,
61 V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
62 V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION,
63 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE,
64 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
65 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE,
66 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE,
67 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE,
68 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER,
69 V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE,
70 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM,
71 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP,
72 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM,
73 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP,
74 0
75};
76
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -030077
78/* Map the control ID to the correct field in the cx2341x_mpeg_params
79 struct. Return -EINVAL if the ID is unknown, else return 0. */
80static int cx2341x_get_ctrl(struct cx2341x_mpeg_params *params,
81 struct v4l2_ext_control *ctrl)
82{
83 switch (ctrl->id) {
84 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
85 ctrl->value = params->audio_sampling_freq;
86 break;
87 case V4L2_CID_MPEG_AUDIO_ENCODING:
88 ctrl->value = params->audio_encoding;
89 break;
90 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
91 ctrl->value = params->audio_l2_bitrate;
92 break;
93 case V4L2_CID_MPEG_AUDIO_MODE:
94 ctrl->value = params->audio_mode;
95 break;
96 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
97 ctrl->value = params->audio_mode_extension;
98 break;
99 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
100 ctrl->value = params->audio_emphasis;
101 break;
102 case V4L2_CID_MPEG_AUDIO_CRC:
103 ctrl->value = params->audio_crc;
104 break;
105 case V4L2_CID_MPEG_VIDEO_ENCODING:
106 ctrl->value = params->video_encoding;
107 break;
108 case V4L2_CID_MPEG_VIDEO_ASPECT:
109 ctrl->value = params->video_aspect;
110 break;
111 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
112 ctrl->value = params->video_b_frames;
113 break;
114 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
115 ctrl->value = params->video_gop_size;
116 break;
117 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
118 ctrl->value = params->video_gop_closure;
119 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300120 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
121 ctrl->value = params->video_bitrate_mode;
122 break;
123 case V4L2_CID_MPEG_VIDEO_BITRATE:
124 ctrl->value = params->video_bitrate;
125 break;
126 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
127 ctrl->value = params->video_bitrate_peak;
128 break;
129 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
130 ctrl->value = params->video_temporal_decimation;
131 break;
132 case V4L2_CID_MPEG_STREAM_TYPE:
133 ctrl->value = params->stream_type;
134 break;
Hans Verkuil8cbde942006-06-24 14:36:02 -0300135 case V4L2_CID_MPEG_STREAM_VBI_FMT:
136 ctrl->value = params->stream_vbi_fmt;
137 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300138 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
139 ctrl->value = params->video_spatial_filter_mode;
140 break;
141 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
142 ctrl->value = params->video_spatial_filter;
143 break;
144 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
145 ctrl->value = params->video_luma_spatial_filter_type;
146 break;
147 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
148 ctrl->value = params->video_chroma_spatial_filter_type;
149 break;
150 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
151 ctrl->value = params->video_temporal_filter_mode;
152 break;
153 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
154 ctrl->value = params->video_temporal_filter;
155 break;
156 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
157 ctrl->value = params->video_median_filter_type;
158 break;
159 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
160 ctrl->value = params->video_luma_median_filter_top;
161 break;
162 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
163 ctrl->value = params->video_luma_median_filter_bottom;
164 break;
165 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
166 ctrl->value = params->video_chroma_median_filter_top;
167 break;
168 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
169 ctrl->value = params->video_chroma_median_filter_bottom;
170 break;
171 default:
172 return -EINVAL;
173 }
174 return 0;
175}
176
177/* Map the control ID to the correct field in the cx2341x_mpeg_params
178 struct. Return -EINVAL if the ID is unknown, else return 0. */
179static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params,
180 struct v4l2_ext_control *ctrl)
181{
182 switch (ctrl->id) {
183 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
184 params->audio_sampling_freq = ctrl->value;
185 break;
186 case V4L2_CID_MPEG_AUDIO_ENCODING:
187 params->audio_encoding = ctrl->value;
188 break;
189 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
190 params->audio_l2_bitrate = ctrl->value;
191 break;
192 case V4L2_CID_MPEG_AUDIO_MODE:
193 params->audio_mode = ctrl->value;
194 break;
195 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
196 params->audio_mode_extension = ctrl->value;
197 break;
198 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
199 params->audio_emphasis = ctrl->value;
200 break;
201 case V4L2_CID_MPEG_AUDIO_CRC:
202 params->audio_crc = ctrl->value;
203 break;
204 case V4L2_CID_MPEG_VIDEO_ASPECT:
205 params->video_aspect = ctrl->value;
206 break;
207 case V4L2_CID_MPEG_VIDEO_B_FRAMES: {
208 int b = ctrl->value + 1;
209 int gop = params->video_gop_size;
210 params->video_b_frames = ctrl->value;
211 params->video_gop_size = b * ((gop + b - 1) / b);
212 /* Max GOP size = 34 */
213 while (params->video_gop_size > 34)
214 params->video_gop_size -= b;
215 break;
216 }
217 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: {
218 int b = params->video_b_frames + 1;
219 int gop = ctrl->value;
220 params->video_gop_size = b * ((gop + b - 1) / b);
221 /* Max GOP size = 34 */
222 while (params->video_gop_size > 34)
223 params->video_gop_size -= b;
224 ctrl->value = params->video_gop_size;
225 break;
226 }
227 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
228 params->video_gop_closure = ctrl->value;
229 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300230 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
231 /* MPEG-1 only allows CBR */
232 if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1 &&
233 ctrl->value != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
234 return -EINVAL;
235 params->video_bitrate_mode = ctrl->value;
236 break;
237 case V4L2_CID_MPEG_VIDEO_BITRATE:
238 params->video_bitrate = ctrl->value;
239 break;
240 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
241 params->video_bitrate_peak = ctrl->value;
242 break;
243 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
244 params->video_temporal_decimation = ctrl->value;
245 break;
246 case V4L2_CID_MPEG_STREAM_TYPE:
247 params->stream_type = ctrl->value;
248 params->video_encoding =
249 (params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_SS ||
250 params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_VCD) ?
251 V4L2_MPEG_VIDEO_ENCODING_MPEG_1 : V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
252 if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) {
253 /* MPEG-1 implies CBR */
254 params->video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
255 }
256 break;
Hans Verkuil8cbde942006-06-24 14:36:02 -0300257 case V4L2_CID_MPEG_STREAM_VBI_FMT:
258 params->stream_vbi_fmt = ctrl->value;
259 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300260 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
261 params->video_spatial_filter_mode = ctrl->value;
262 break;
263 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
264 params->video_spatial_filter = ctrl->value;
265 break;
266 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
267 params->video_luma_spatial_filter_type = ctrl->value;
268 break;
269 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
270 params->video_chroma_spatial_filter_type = ctrl->value;
271 break;
272 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
273 params->video_temporal_filter_mode = ctrl->value;
274 break;
275 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
276 params->video_temporal_filter = ctrl->value;
277 break;
278 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
279 params->video_median_filter_type = ctrl->value;
280 break;
281 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
282 params->video_luma_median_filter_top = ctrl->value;
283 break;
284 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
285 params->video_luma_median_filter_bottom = ctrl->value;
286 break;
287 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
288 params->video_chroma_median_filter_top = ctrl->value;
289 break;
290 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
291 params->video_chroma_median_filter_bottom = ctrl->value;
292 break;
293 default:
294 return -EINVAL;
295 }
296 return 0;
297}
298
299static int cx2341x_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def)
300{
301 const char *name;
302
303 qctrl->flags = 0;
304 switch (qctrl->id) {
305 /* MPEG controls */
306 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
307 name = "Spatial Filter Mode";
308 break;
309 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
310 name = "Spatial Filter";
311 break;
312 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
313 name = "Spatial Luma Filter Type";
314 break;
315 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
316 name = "Spatial Chroma Filter Type";
317 break;
318 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
319 name = "Temporal Filter Mode";
320 break;
321 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
322 name = "Temporal Filter";
323 break;
324 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
325 name = "Median Filter Type";
326 break;
327 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
328 name = "Median Luma Filter Maximum";
329 break;
330 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
331 name = "Median Luma Filter Minimum";
332 break;
333 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
334 name = "Median Chroma Filter Maximum";
335 break;
336 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
337 name = "Median Chroma Filter Minimum";
338 break;
339
340 default:
341 return v4l2_ctrl_query_fill(qctrl, min, max, step, def);
342 }
343 switch (qctrl->id) {
344 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
345 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
346 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
347 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
348 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
349 qctrl->type = V4L2_CTRL_TYPE_MENU;
350 min = 0;
351 step = 1;
352 break;
353 default:
354 qctrl->type = V4L2_CTRL_TYPE_INTEGER;
355 break;
356 }
357 switch (qctrl->id) {
358 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
359 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
360 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
361 qctrl->flags |= V4L2_CTRL_FLAG_UPDATE;
362 break;
363 }
364 qctrl->minimum = min;
365 qctrl->maximum = max;
366 qctrl->step = step;
367 qctrl->default_value = def;
368 qctrl->reserved[0] = qctrl->reserved[1] = 0;
369 snprintf(qctrl->name, sizeof(qctrl->name), name);
370 return 0;
371}
372
373int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params, struct v4l2_queryctrl *qctrl)
374{
375 int err;
376
377 switch (qctrl->id) {
378 case V4L2_CID_MPEG_AUDIO_ENCODING:
379 return v4l2_ctrl_query_fill(qctrl,
380 V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
381 V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1,
382 V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
383
384 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
385 return v4l2_ctrl_query_fill(qctrl,
386 V4L2_MPEG_AUDIO_L2_BITRATE_192K,
387 V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
388 V4L2_MPEG_AUDIO_L2_BITRATE_224K);
389
390 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
391 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
392 return -EINVAL;
393
394 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
395 err = v4l2_ctrl_query_fill_std(qctrl);
396 if (err == 0 && params->audio_mode != V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
397 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
398 return err;
399
400 case V4L2_CID_MPEG_VIDEO_ENCODING:
401 /* this setting is read-only for the cx2341x since the
402 V4L2_CID_MPEG_STREAM_TYPE really determines the
403 MPEG-1/2 setting */
404 err = v4l2_ctrl_query_fill_std(qctrl);
405 if (err == 0)
406 qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
407 return err;
408
Hans Verkuil54aa9a22006-06-19 18:00:06 -0300409 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
410 err = v4l2_ctrl_query_fill_std(qctrl);
411 if (err == 0 && params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
412 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
413 return err;
414
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300415 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
416 err = v4l2_ctrl_query_fill_std(qctrl);
417 if (err == 0 && params->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
418 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
419 return err;
420
Hans Verkuil8cbde942006-06-24 14:36:02 -0300421 case V4L2_CID_MPEG_STREAM_VBI_FMT:
422 if (params->capabilities & CX2341X_CAP_HAS_SLICED_VBI)
423 return v4l2_ctrl_query_fill_std(qctrl);
424 return cx2341x_ctrl_query_fill(qctrl,
425 V4L2_MPEG_STREAM_VBI_FMT_NONE,
426 V4L2_MPEG_STREAM_VBI_FMT_NONE, 1,
427 V4L2_MPEG_STREAM_VBI_FMT_NONE);
428
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300429 /* CX23415/6 specific */
430 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
431 return cx2341x_ctrl_query_fill(qctrl,
432 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
433 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO, 1,
434 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL);
435
436 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
437 cx2341x_ctrl_query_fill(qctrl, 0, 15, 1, 0);
438 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
439 if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
440 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
441 return 0;
442
443 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
444 cx2341x_ctrl_query_fill(qctrl,
445 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF,
446 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE, 1,
447 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF);
448 if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
449 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
450 return 0;
451
452 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
453 cx2341x_ctrl_query_fill(qctrl,
454 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF,
455 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR, 1,
456 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF);
457 if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
458 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
459 return 0;
460
461 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
462 return cx2341x_ctrl_query_fill(qctrl,
463 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
464 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO, 1,
465 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL);
466
467 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
468 cx2341x_ctrl_query_fill(qctrl, 0, 31, 1, 0);
469 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
470 if (params->video_temporal_filter_mode == V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO)
471 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
472 return 0;
473
474 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
475 return cx2341x_ctrl_query_fill(qctrl,
476 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
477 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG, 1,
478 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF);
479
480 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
481 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 255);
482 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
483 if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
484 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
485 return 0;
486
487 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
488 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 0);
489 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
490 if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
491 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
492 return 0;
493
494 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
495 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 255);
496 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
497 if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
498 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
499 return 0;
500
501 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
502 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 0);
503 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
504 if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
505 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
506 return 0;
507
508 default:
509 return v4l2_ctrl_query_fill_std(qctrl);
510
511 }
512}
513
514const char **cx2341x_ctrl_get_menu(u32 id)
515{
516 static const char *mpeg_stream_type[] = {
517 "MPEG-2 Program Stream",
518 "",
519 "MPEG-1 System Stream",
520 "MPEG-2 DVD-compatible Stream",
521 "MPEG-1 VCD-compatible Stream",
522 "MPEG-2 SVCD-compatible Stream",
523 NULL
524 };
525
526 static const char *cx2341x_video_spatial_filter_mode_menu[] = {
527 "Manual",
528 "Auto",
529 NULL
530 };
531
532 static const char *cx2341x_video_luma_spatial_filter_type_menu[] = {
533 "Off",
534 "1D Horizontal",
535 "1D Vertical",
536 "2D H/V Separable",
537 "2D Symmetric non-separable",
538 NULL
539 };
540
541 static const char *cx2341x_video_chroma_spatial_filter_type_menu[] = {
542 "Off",
543 "1D Horizontal",
544 NULL
545 };
546
547 static const char *cx2341x_video_temporal_filter_mode_menu[] = {
548 "Manual",
549 "Auto",
550 NULL
551 };
552
553 static const char *cx2341x_video_median_filter_type_menu[] = {
554 "Off",
555 "Horizontal",
556 "Vertical",
557 "Horizontal/Vertical",
558 "Diagonal",
559 NULL
560 };
561
562 switch (id) {
563 case V4L2_CID_MPEG_STREAM_TYPE:
564 return mpeg_stream_type;
565 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
566 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
567 return NULL;
568 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
569 return cx2341x_video_spatial_filter_mode_menu;
570 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
571 return cx2341x_video_luma_spatial_filter_type_menu;
572 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
573 return cx2341x_video_chroma_spatial_filter_type_menu;
574 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
575 return cx2341x_video_temporal_filter_mode_menu;
576 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
577 return cx2341x_video_median_filter_type_menu;
578 default:
579 return v4l2_ctrl_get_menu(id);
580 }
581}
582
583static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params)
584{
585 params->audio_properties = (params->audio_sampling_freq << 0) |
586 ((3 - params->audio_encoding) << 2) |
587 ((1 + params->audio_l2_bitrate) << 4) |
588 (params->audio_mode << 8) |
589 (params->audio_mode_extension << 10) |
590 (((params->audio_emphasis == V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17) ?
591 3 :
592 params->audio_emphasis) << 12) |
593 (params->audio_crc << 14);
594}
595
596int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params,
Hans Verkuil4d6b5ae2006-06-26 09:31:18 -0300597 struct v4l2_ext_controls *ctrls, unsigned int cmd)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300598{
599 int err = 0;
600 int i;
601
602 if (cmd == VIDIOC_G_EXT_CTRLS) {
603 for (i = 0; i < ctrls->count; i++) {
604 struct v4l2_ext_control *ctrl = ctrls->controls + i;
605
606 err = cx2341x_get_ctrl(params, ctrl);
607 if (err) {
608 ctrls->error_idx = i;
609 break;
610 }
611 }
612 return err;
613 }
614 for (i = 0; i < ctrls->count; i++) {
615 struct v4l2_ext_control *ctrl = ctrls->controls + i;
616 struct v4l2_queryctrl qctrl;
617 const char **menu_items = NULL;
618
619 qctrl.id = ctrl->id;
620 err = cx2341x_ctrl_query(params, &qctrl);
621 if (err)
622 break;
623 if (qctrl.type == V4L2_CTRL_TYPE_MENU)
624 menu_items = cx2341x_ctrl_get_menu(qctrl.id);
625 err = v4l2_ctrl_check(ctrl, &qctrl, menu_items);
626 if (err)
627 break;
628 err = cx2341x_set_ctrl(params, ctrl);
629 if (err)
630 break;
631 }
632 if (err == 0 && params->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
633 params->video_bitrate_peak < params->video_bitrate) {
634 err = -ERANGE;
635 ctrls->error_idx = ctrls->count;
636 }
637 if (err) {
638 ctrls->error_idx = i;
639 }
640 else {
641 cx2341x_calc_audio_properties(params);
642 }
643 return err;
644}
645
646void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p)
647{
648 static struct cx2341x_mpeg_params default_params = {
649 /* misc */
Hans Verkuil8cbde942006-06-24 14:36:02 -0300650 .capabilities = 0,
Hans Verkuil45ad9f82006-06-21 17:04:13 -0300651 .port = CX2341X_PORT_MEMORY,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300652 .width = 720,
653 .height = 480,
654 .is_50hz = 0,
655
656 /* stream */
657 .stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
Hans Verkuil8cbde942006-06-24 14:36:02 -0300658 .stream_vbi_fmt = V4L2_MPEG_STREAM_VBI_FMT_NONE,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300659
660 /* audio */
661 .audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
662 .audio_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
663 .audio_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_224K,
664 .audio_mode = V4L2_MPEG_AUDIO_MODE_STEREO,
665 .audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
666 .audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE,
667 .audio_crc = V4L2_MPEG_AUDIO_CRC_NONE,
668
669 /* video */
670 .video_encoding = V4L2_MPEG_VIDEO_ENCODING_MPEG_2,
671 .video_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3,
672 .video_b_frames = 2,
673 .video_gop_size = 12,
674 .video_gop_closure = 1,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300675 .video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
676 .video_bitrate = 6000000,
677 .video_bitrate_peak = 8000000,
678 .video_temporal_decimation = 0,
679
680 /* encoding filters */
681 .video_spatial_filter_mode = V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
682 .video_spatial_filter = 0,
683 .video_luma_spatial_filter_type = V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR,
684 .video_chroma_spatial_filter_type = V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
685 .video_temporal_filter_mode = V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
Hans Verkuil44b579d2006-08-27 19:22:15 -0300686 .video_temporal_filter = 8,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300687 .video_median_filter_type = V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
688 .video_luma_median_filter_top = 255,
689 .video_luma_median_filter_bottom = 0,
690 .video_chroma_median_filter_top = 255,
691 .video_chroma_median_filter_bottom = 0,
692 };
693
694 *p = default_params;
695 cx2341x_calc_audio_properties(p);
696}
697
698static int cx2341x_api(void *priv, cx2341x_mbox_func func, int cmd, int args, ...)
699{
700 u32 data[CX2341X_MBOX_MAX_DATA];
701 va_list vargs;
702 int i;
703
704 va_start(vargs, args);
705
706 for (i = 0; i < args; i++) {
707 data[i] = va_arg(vargs, int);
708 }
709 va_end(vargs);
710 return func(priv, cmd, args, 0, data);
711}
712
713int cx2341x_update(void *priv, cx2341x_mbox_func func,
714 const struct cx2341x_mpeg_params *old, const struct cx2341x_mpeg_params *new)
715{
716 static int mpeg_stream_type[] = {
717 0, /* MPEG-2 PS */
718 1, /* MPEG-2 TS */
719 2, /* MPEG-1 SS */
720 14, /* DVD */
721 11, /* VCD */
722 12, /* SVCD */
723 };
724
725 int err = 0;
Hans Verkuil44b579d2006-08-27 19:22:15 -0300726 u16 temporal = new->video_temporal_filter;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300727
Hans Verkuil45ad9f82006-06-21 17:04:13 -0300728 cx2341x_api(priv, func, CX2341X_ENC_SET_OUTPUT_PORT, 2, new->port, 0);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300729
730 if (old == NULL || old->is_50hz != new->is_50hz) {
731 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_RATE, 1, new->is_50hz);
732 if (err) return err;
733 }
734
735 if (old == NULL || old->width != new->width || old->height != new->height ||
736 old->video_encoding != new->video_encoding) {
737 u16 w = new->width;
738 u16 h = new->height;
739
740 if (new->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) {
741 w /= 2;
742 h /= 2;
743 }
744 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_SIZE, 2, h, w);
745 if (err) return err;
Hans Verkuil12b896e2006-12-18 13:37:50 -0300746 }
Hans Verkuil44b579d2006-08-27 19:22:15 -0300747
Hans Verkuil12b896e2006-12-18 13:37:50 -0300748 if (new->width != 720 || new->height != (new->is_50hz ? 576 : 480)) {
Hans Verkuil44b579d2006-08-27 19:22:15 -0300749 /* Adjust temporal filter if necessary. The problem with the temporal
750 filter is that it works well with full resolution capturing, but
751 not when the capture window is scaled (the filter introduces
Hans Verkuil12b896e2006-12-18 13:37:50 -0300752 a ghosting effect). So if the capture window is scaled, then
753 force the filter to 0.
Hans Verkuil44b579d2006-08-27 19:22:15 -0300754
Hans Verkuil12b896e2006-12-18 13:37:50 -0300755 For full resolution the filter really improves the video
Hans Verkuil44b579d2006-08-27 19:22:15 -0300756 quality, especially if the original video quality is suboptimal. */
Hans Verkuil12b896e2006-12-18 13:37:50 -0300757 temporal = 0;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300758 }
759
760 if (old == NULL || old->stream_type != new->stream_type) {
761 err = cx2341x_api(priv, func, CX2341X_ENC_SET_STREAM_TYPE, 1, mpeg_stream_type[new->stream_type]);
762 if (err) return err;
763 }
764 if (old == NULL || old->video_aspect != new->video_aspect) {
765 err = cx2341x_api(priv, func, CX2341X_ENC_SET_ASPECT_RATIO, 1, 1 + new->video_aspect);
766 if (err) return err;
767 }
768 if (old == NULL || old->video_b_frames != new->video_b_frames ||
769 old->video_gop_size != new->video_gop_size) {
770 err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_PROPERTIES, 2,
771 new->video_gop_size, new->video_b_frames + 1);
772 if (err) return err;
773 }
774 if (old == NULL || old->video_gop_closure != new->video_gop_closure) {
775 err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_CLOSURE, 1, new->video_gop_closure);
776 if (err) return err;
777 }
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300778 if (old == NULL || old->audio_properties != new->audio_properties) {
779 err = cx2341x_api(priv, func, CX2341X_ENC_SET_AUDIO_PROPERTIES, 1, new->audio_properties);
780 if (err) return err;
781 }
782 if (old == NULL || old->video_bitrate_mode != new->video_bitrate_mode ||
783 old->video_bitrate != new->video_bitrate ||
784 old->video_bitrate_peak != new->video_bitrate_peak) {
785 err = cx2341x_api(priv, func, CX2341X_ENC_SET_BIT_RATE, 5,
786 new->video_bitrate_mode, new->video_bitrate,
787 new->video_bitrate_peak / 400, 0, 0);
788 if (err) return err;
789 }
790 if (old == NULL || old->video_spatial_filter_mode != new->video_spatial_filter_mode ||
791 old->video_temporal_filter_mode != new->video_temporal_filter_mode ||
792 old->video_median_filter_type != new->video_median_filter_type) {
793 err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_MODE, 2,
794 new->video_spatial_filter_mode | (new->video_temporal_filter_mode << 1),
795 new->video_median_filter_type);
796 if (err) return err;
797 }
798 if (old == NULL ||
799 old->video_luma_median_filter_bottom != new->video_luma_median_filter_bottom ||
800 old->video_luma_median_filter_top != new->video_luma_median_filter_top ||
801 old->video_chroma_median_filter_bottom != new->video_chroma_median_filter_bottom ||
802 old->video_chroma_median_filter_top != new->video_chroma_median_filter_top) {
803 err = cx2341x_api(priv, func, CX2341X_ENC_SET_CORING_LEVELS, 4,
804 new->video_luma_median_filter_bottom,
805 new->video_luma_median_filter_top,
806 new->video_chroma_median_filter_bottom,
807 new->video_chroma_median_filter_top);
808 if (err) return err;
809 }
810 if (old == NULL ||
811 old->video_luma_spatial_filter_type != new->video_luma_spatial_filter_type ||
812 old->video_chroma_spatial_filter_type != new->video_chroma_spatial_filter_type) {
813 err = cx2341x_api(priv, func, CX2341X_ENC_SET_SPATIAL_FILTER_TYPE, 2,
814 new->video_luma_spatial_filter_type, new->video_chroma_spatial_filter_type);
815 if (err) return err;
816 }
817 if (old == NULL ||
818 old->video_spatial_filter != new->video_spatial_filter ||
Hans Verkuil44b579d2006-08-27 19:22:15 -0300819 old->video_temporal_filter != temporal) {
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300820 err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_PROPS, 2,
Hans Verkuil44b579d2006-08-27 19:22:15 -0300821 new->video_spatial_filter, temporal);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300822 if (err) return err;
823 }
824 if (old == NULL || old->video_temporal_decimation != new->video_temporal_decimation) {
825 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_DROP_RATE, 1,
826 new->video_temporal_decimation);
827 if (err) return err;
828 }
829 return 0;
830}
831
832static const char *cx2341x_menu_item(struct cx2341x_mpeg_params *p, u32 id)
833{
834 const char **menu = cx2341x_ctrl_get_menu(id);
835 struct v4l2_ext_control ctrl;
836
837 if (menu == NULL)
838 goto invalid;
839 ctrl.id = id;
840 if (cx2341x_get_ctrl(p, &ctrl))
841 goto invalid;
842 while (ctrl.value-- && *menu) menu++;
843 if (*menu == NULL)
844 goto invalid;
845 return *menu;
846
847invalid:
848 return "<invalid>";
849}
850
Hans Verkuil99eb44f2006-06-26 18:24:05 -0300851void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300852{
853 int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
Hans Verkuil83aaf132006-12-18 13:40:23 -0300854 int temporal = p->video_temporal_filter;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300855
856 /* Stream */
Hans Verkuil99eb44f2006-06-26 18:24:05 -0300857 printk(KERN_INFO "%s: Stream: %s\n",
858 prefix,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300859 cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE));
Hans Verkuil44b579d2006-08-27 19:22:15 -0300860 printk(KERN_INFO "%s: VBI Format: %s\n",
861 prefix,
862 cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_VBI_FMT));
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300863
864 /* Video */
Hans Verkuil99eb44f2006-06-26 18:24:05 -0300865 printk(KERN_INFO "%s: Video: %dx%d, %d fps\n",
866 prefix,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300867 p->width / (is_mpeg1 ? 2 : 1), p->height / (is_mpeg1 ? 2 : 1),
868 p->is_50hz ? 25 : 30);
Hans Verkuil99eb44f2006-06-26 18:24:05 -0300869 printk(KERN_INFO "%s: Video: %s, %s, %s, %d",
870 prefix,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300871 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ENCODING),
872 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ASPECT),
873 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_BITRATE_MODE),
874 p->video_bitrate);
875 if (p->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) {
876 printk(", Peak %d", p->video_bitrate_peak);
877 }
878 printk("\n");
Hans Verkuil75558ab2006-12-18 22:52:21 -0300879 printk(KERN_INFO "%s: Video: GOP Size %d, %d B-Frames, %sGOP Closure\n",
Hans Verkuil99eb44f2006-06-26 18:24:05 -0300880 prefix,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300881 p->video_gop_size, p->video_b_frames,
Hans Verkuil75558ab2006-12-18 22:52:21 -0300882 p->video_gop_closure ? "" : "No ");
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300883 if (p->video_temporal_decimation) {
Hans Verkuil99eb44f2006-06-26 18:24:05 -0300884 printk(KERN_INFO "%s: Video: Temporal Decimation %d\n",
885 prefix, p->video_temporal_decimation);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300886 }
887
888 /* Audio */
Hans Verkuil99eb44f2006-06-26 18:24:05 -0300889 printk(KERN_INFO "%s: Audio: %s, %s, %s, %s",
890 prefix,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300891 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ),
892 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING),
893 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_L2_BITRATE),
894 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE));
895 if (p->audio_mode == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO) {
896 printk(", %s",
897 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE_EXTENSION));
898 }
899 printk(", %s, %s\n",
900 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_EMPHASIS),
901 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_CRC));
902
903 /* Encoding filters */
Hans Verkuil99eb44f2006-06-26 18:24:05 -0300904 printk(KERN_INFO "%s: Spatial Filter: %s, Luma %s, Chroma %s, %d\n",
905 prefix,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300906 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE),
907 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE),
908 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE),
909 p->video_spatial_filter);
Hans Verkuil83aaf132006-12-18 13:40:23 -0300910 if (p->width != 720 || p->height != (p->is_50hz ? 576 : 480)) {
911 temporal = 0;
912 }
Hans Verkuil99eb44f2006-06-26 18:24:05 -0300913 printk(KERN_INFO "%s: Temporal Filter: %s, %d\n",
914 prefix,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300915 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE),
Hans Verkuil83aaf132006-12-18 13:40:23 -0300916 temporal);
Hans Verkuil99eb44f2006-06-26 18:24:05 -0300917 printk(KERN_INFO "%s: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n",
918 prefix,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300919 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE),
920 p->video_luma_median_filter_bottom,
921 p->video_luma_median_filter_top,
922 p->video_chroma_median_filter_bottom,
923 p->video_chroma_median_filter_top);
924}
925
926EXPORT_SYMBOL(cx2341x_fill_defaults);
927EXPORT_SYMBOL(cx2341x_ctrl_query);
928EXPORT_SYMBOL(cx2341x_ctrl_get_menu);
929EXPORT_SYMBOL(cx2341x_ext_ctrls);
930EXPORT_SYMBOL(cx2341x_update);
931EXPORT_SYMBOL(cx2341x_log_status);
Hans Verkuilcc7bc642006-06-19 17:53:08 -0300932EXPORT_SYMBOL(cx2341x_mpeg_ctrls);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300933
934/*
935 * Local variables:
936 * c-basic-offset: 8
937 * End:
938 */
939