diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2006-06-18 15:40:10 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-06-25 01:05:23 -0400 |
commit | 86b79d662453b0f0107d03cc939dd737d6076436 (patch) | |
tree | f61a827c0d10a93a93a948ab66ee602777fc8eb2 /drivers/media/video/saa7134/saa6752hs.c | |
parent | f022156b33ffa32c26a86540fe4f6fe56cff0963 (diff) |
V4L/DVB (4197): Port new MPEG API to saa7134-empress with saa6752hs
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/saa7134/saa6752hs.c')
-rw-r--r-- | drivers/media/video/saa7134/saa6752hs.c | 259 |
1 files changed, 228 insertions, 31 deletions
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c index a95878004f93..e8c65ddd0181 100644 --- a/drivers/media/video/saa7134/saa6752hs.c +++ b/drivers/media/video/saa7134/saa6752hs.c | |||
@@ -39,6 +39,23 @@ enum saa6752hs_videoformat { | |||
39 | SAA6752HS_VF_UNKNOWN, | 39 | SAA6752HS_VF_UNKNOWN, |
40 | }; | 40 | }; |
41 | 41 | ||
42 | struct saa6752hs_mpeg_params { | ||
43 | /* transport streams */ | ||
44 | __u16 ts_pid_pmt; | ||
45 | __u16 ts_pid_audio; | ||
46 | __u16 ts_pid_video; | ||
47 | __u16 ts_pid_pcr; | ||
48 | |||
49 | /* audio */ | ||
50 | enum v4l2_mpeg_audio_l2_bitrate au_l2_bitrate; | ||
51 | |||
52 | /* video */ | ||
53 | enum v4l2_mpeg_video_aspect vi_aspect; | ||
54 | enum v4l2_mpeg_video_bitrate_mode vi_bitrate_mode; | ||
55 | __u32 vi_bitrate; | ||
56 | __u32 vi_bitrate_peak; | ||
57 | }; | ||
58 | |||
42 | static const struct v4l2_format v4l2_format_table[] = | 59 | static const struct v4l2_format v4l2_format_table[] = |
43 | { | 60 | { |
44 | [SAA6752HS_VF_D1] = | 61 | [SAA6752HS_VF_D1] = |
@@ -55,7 +72,8 @@ static const struct v4l2_format v4l2_format_table[] = | |||
55 | 72 | ||
56 | struct saa6752hs_state { | 73 | struct saa6752hs_state { |
57 | struct i2c_client client; | 74 | struct i2c_client client; |
58 | struct v4l2_mpeg_compression params; | 75 | struct v4l2_mpeg_compression old_params; |
76 | struct saa6752hs_mpeg_params params; | ||
59 | enum saa6752hs_videoformat video_format; | 77 | enum saa6752hs_videoformat video_format; |
60 | v4l2_std_id standard; | 78 | v4l2_std_id standard; |
61 | }; | 79 | }; |
@@ -129,7 +147,22 @@ static u8 PMT[] = { | |||
129 | 0x00, 0x00, 0x00, 0x00 /* CRC32 */ | 147 | 0x00, 0x00, 0x00, 0x00 /* CRC32 */ |
130 | }; | 148 | }; |
131 | 149 | ||
132 | static struct v4l2_mpeg_compression param_defaults = | 150 | static struct saa6752hs_mpeg_params param_defaults = |
151 | { | ||
152 | .ts_pid_pmt = 16, | ||
153 | .ts_pid_video = 260, | ||
154 | .ts_pid_audio = 256, | ||
155 | .ts_pid_pcr = 259, | ||
156 | |||
157 | .vi_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3, | ||
158 | .vi_bitrate = 4000, | ||
159 | .vi_bitrate_peak = 6000, | ||
160 | .vi_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, | ||
161 | |||
162 | .au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_256K, | ||
163 | }; | ||
164 | |||
165 | static struct v4l2_mpeg_compression old_param_defaults = | ||
133 | { | 166 | { |
134 | .st_type = V4L2_MPEG_TS_2, | 167 | .st_type = V4L2_MPEG_TS_2, |
135 | .st_bitrate = { | 168 | .st_bitrate = { |
@@ -318,50 +351,188 @@ static void saa6752hs_set_subsampling(struct i2c_client* client, | |||
318 | } | 351 | } |
319 | 352 | ||
320 | 353 | ||
321 | static void saa6752hs_set_params(struct i2c_client* client, | 354 | static void saa6752hs_old_set_params(struct i2c_client* client, |
322 | struct v4l2_mpeg_compression* params) | 355 | struct v4l2_mpeg_compression* params) |
323 | { | 356 | { |
324 | struct saa6752hs_state *h = i2c_get_clientdata(client); | 357 | struct saa6752hs_state *h = i2c_get_clientdata(client); |
325 | 358 | ||
326 | /* check PIDs */ | 359 | /* check PIDs */ |
327 | if (params->ts_pid_pmt <= MPEG_PID_MAX) | 360 | if (params->ts_pid_pmt <= MPEG_PID_MAX) { |
361 | h->old_params.ts_pid_pmt = params->ts_pid_pmt; | ||
328 | h->params.ts_pid_pmt = params->ts_pid_pmt; | 362 | h->params.ts_pid_pmt = params->ts_pid_pmt; |
329 | if (params->ts_pid_pcr <= MPEG_PID_MAX) | 363 | } |
364 | if (params->ts_pid_pcr <= MPEG_PID_MAX) { | ||
365 | h->old_params.ts_pid_pcr = params->ts_pid_pcr; | ||
330 | h->params.ts_pid_pcr = params->ts_pid_pcr; | 366 | h->params.ts_pid_pcr = params->ts_pid_pcr; |
331 | if (params->ts_pid_video <= MPEG_PID_MAX) | 367 | } |
368 | if (params->ts_pid_video <= MPEG_PID_MAX) { | ||
369 | h->old_params.ts_pid_video = params->ts_pid_video; | ||
332 | h->params.ts_pid_video = params->ts_pid_video; | 370 | h->params.ts_pid_video = params->ts_pid_video; |
333 | if (params->ts_pid_audio <= MPEG_PID_MAX) | 371 | } |
372 | if (params->ts_pid_audio <= MPEG_PID_MAX) { | ||
373 | h->old_params.ts_pid_audio = params->ts_pid_audio; | ||
334 | h->params.ts_pid_audio = params->ts_pid_audio; | 374 | h->params.ts_pid_audio = params->ts_pid_audio; |
375 | } | ||
335 | 376 | ||
336 | /* check bitrate parameters */ | 377 | /* check bitrate parameters */ |
337 | if ((params->vi_bitrate.mode == V4L2_BITRATE_CBR) || | 378 | if ((params->vi_bitrate.mode == V4L2_BITRATE_CBR) || |
338 | (params->vi_bitrate.mode == V4L2_BITRATE_VBR)) | 379 | (params->vi_bitrate.mode == V4L2_BITRATE_VBR)) { |
339 | h->params.vi_bitrate.mode = params->vi_bitrate.mode; | 380 | h->old_params.vi_bitrate.mode = params->vi_bitrate.mode; |
381 | h->params.vi_bitrate_mode = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ? | ||
382 | V4L2_MPEG_VIDEO_BITRATE_MODE_VBR : V4L2_MPEG_VIDEO_BITRATE_MODE_CBR; | ||
383 | } | ||
340 | if (params->vi_bitrate.mode != V4L2_BITRATE_NONE) | 384 | if (params->vi_bitrate.mode != V4L2_BITRATE_NONE) |
341 | h->params.st_bitrate.target = params->st_bitrate.target; | 385 | h->old_params.st_bitrate.target = params->st_bitrate.target; |
342 | if (params->vi_bitrate.mode != V4L2_BITRATE_NONE) | 386 | if (params->vi_bitrate.mode != V4L2_BITRATE_NONE) |
343 | h->params.vi_bitrate.target = params->vi_bitrate.target; | 387 | h->old_params.vi_bitrate.target = params->vi_bitrate.target; |
344 | if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) | 388 | if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) |
345 | h->params.vi_bitrate.max = params->vi_bitrate.max; | 389 | h->old_params.vi_bitrate.max = params->vi_bitrate.max; |
346 | if (params->au_bitrate.mode != V4L2_BITRATE_NONE) | 390 | if (params->au_bitrate.mode != V4L2_BITRATE_NONE) |
347 | h->params.au_bitrate.target = params->au_bitrate.target; | 391 | h->old_params.au_bitrate.target = params->au_bitrate.target; |
348 | 392 | ||
349 | /* aspect ratio */ | 393 | /* aspect ratio */ |
350 | if (params->vi_aspect_ratio == V4L2_MPEG_ASPECT_4_3 || | 394 | if (params->vi_aspect_ratio == V4L2_MPEG_ASPECT_4_3 || |
351 | params->vi_aspect_ratio == V4L2_MPEG_ASPECT_16_9) | 395 | params->vi_aspect_ratio == V4L2_MPEG_ASPECT_16_9) { |
352 | h->params.vi_aspect_ratio = params->vi_aspect_ratio; | 396 | h->old_params.vi_aspect_ratio = params->vi_aspect_ratio; |
397 | if (params->vi_aspect_ratio == V4L2_MPEG_ASPECT_4_3) | ||
398 | h->params.vi_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3; | ||
399 | else | ||
400 | h->params.vi_aspect = V4L2_MPEG_VIDEO_ASPECT_16x9; | ||
401 | } | ||
353 | 402 | ||
354 | /* range checks */ | 403 | /* range checks */ |
355 | if (h->params.st_bitrate.target > MPEG_TOTAL_TARGET_BITRATE_MAX) | 404 | if (h->old_params.st_bitrate.target > MPEG_TOTAL_TARGET_BITRATE_MAX) |
356 | h->params.st_bitrate.target = MPEG_TOTAL_TARGET_BITRATE_MAX; | 405 | h->old_params.st_bitrate.target = MPEG_TOTAL_TARGET_BITRATE_MAX; |
357 | if (h->params.vi_bitrate.target > MPEG_VIDEO_TARGET_BITRATE_MAX) | 406 | if (h->old_params.vi_bitrate.target > MPEG_VIDEO_TARGET_BITRATE_MAX) |
358 | h->params.vi_bitrate.target = MPEG_VIDEO_TARGET_BITRATE_MAX; | 407 | h->old_params.vi_bitrate.target = MPEG_VIDEO_TARGET_BITRATE_MAX; |
359 | if (h->params.vi_bitrate.max > MPEG_VIDEO_MAX_BITRATE_MAX) | 408 | if (h->old_params.vi_bitrate.max > MPEG_VIDEO_MAX_BITRATE_MAX) |
360 | h->params.vi_bitrate.max = MPEG_VIDEO_MAX_BITRATE_MAX; | 409 | h->old_params.vi_bitrate.max = MPEG_VIDEO_MAX_BITRATE_MAX; |
361 | if (h->params.au_bitrate.target <= 256) | 410 | h->params.vi_bitrate = params->vi_bitrate.target; |
362 | h->params.au_bitrate.target = 256; | 411 | h->params.vi_bitrate_peak = params->vi_bitrate.max; |
412 | if (h->old_params.au_bitrate.target <= 256) { | ||
413 | h->old_params.au_bitrate.target = 256; | ||
414 | h->params.au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_256K; | ||
415 | } | ||
416 | else { | ||
417 | h->old_params.au_bitrate.target = 384; | ||
418 | h->params.au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_384K; | ||
419 | } | ||
420 | } | ||
421 | |||
422 | static int handle_ctrl(struct saa6752hs_mpeg_params *params, | ||
423 | struct v4l2_ext_control *ctrl, int cmd) | ||
424 | { | ||
425 | int old = 0, new; | ||
426 | int set = cmd == VIDIOC_S_EXT_CTRLS; | ||
427 | |||
428 | new = ctrl->value; | ||
429 | switch (ctrl->id) { | ||
430 | case V4L2_CID_MPEG_STREAM_TYPE: | ||
431 | old = V4L2_MPEG_STREAM_TYPE_MPEG2_TS; | ||
432 | if (set && new != old) | ||
433 | return -ERANGE; | ||
434 | new = old; | ||
435 | break; | ||
436 | case V4L2_CID_MPEG_STREAM_PID_PMT: | ||
437 | old = params->ts_pid_pmt; | ||
438 | if (set && new > MPEG_PID_MAX) | ||
439 | return -ERANGE; | ||
440 | if (new > MPEG_PID_MAX) | ||
441 | new = MPEG_PID_MAX; | ||
442 | params->ts_pid_pmt = new; | ||
443 | break; | ||
444 | case V4L2_CID_MPEG_STREAM_PID_AUDIO: | ||
445 | old = params->ts_pid_audio; | ||
446 | if (set && new > MPEG_PID_MAX) | ||
447 | return -ERANGE; | ||
448 | if (new > MPEG_PID_MAX) | ||
449 | new = MPEG_PID_MAX; | ||
450 | params->ts_pid_audio = new; | ||
451 | break; | ||
452 | case V4L2_CID_MPEG_STREAM_PID_VIDEO: | ||
453 | old = params->ts_pid_video; | ||
454 | if (set && new > MPEG_PID_MAX) | ||
455 | return -ERANGE; | ||
456 | if (new > MPEG_PID_MAX) | ||
457 | new = MPEG_PID_MAX; | ||
458 | params->ts_pid_video = new; | ||
459 | break; | ||
460 | case V4L2_CID_MPEG_STREAM_PID_PCR: | ||
461 | old = params->ts_pid_pcr; | ||
462 | if (set && new > MPEG_PID_MAX) | ||
463 | return -ERANGE; | ||
464 | if (new > MPEG_PID_MAX) | ||
465 | new = MPEG_PID_MAX; | ||
466 | params->ts_pid_pcr = new; | ||
467 | break; | ||
468 | case V4L2_CID_MPEG_AUDIO_ENCODING: | ||
469 | old = V4L2_MPEG_AUDIO_ENCODING_LAYER_2; | ||
470 | if (set && new != old) | ||
471 | return -ERANGE; | ||
472 | new = old; | ||
473 | break; | ||
474 | case V4L2_CID_MPEG_AUDIO_L2_BITRATE: | ||
475 | old = params->au_l2_bitrate; | ||
476 | if (set && new != V4L2_MPEG_AUDIO_L2_BITRATE_256K && | ||
477 | new != V4L2_MPEG_AUDIO_L2_BITRATE_384K) | ||
478 | return -ERANGE; | ||
479 | if (new <= V4L2_MPEG_AUDIO_L2_BITRATE_256K) | ||
480 | new = V4L2_MPEG_AUDIO_L2_BITRATE_256K; | ||
481 | else | ||
482 | new = V4L2_MPEG_AUDIO_L2_BITRATE_384K; | ||
483 | params->au_l2_bitrate = new; | ||
484 | break; | ||
485 | case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: | ||
486 | old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000; | ||
487 | if (set && new != old) | ||
488 | return -ERANGE; | ||
489 | new = old; | ||
490 | break; | ||
491 | case V4L2_CID_MPEG_VIDEO_ENCODING: | ||
492 | old = V4L2_MPEG_VIDEO_ENCODING_MPEG_2; | ||
493 | if (set && new != old) | ||
494 | return -ERANGE; | ||
495 | new = old; | ||
496 | break; | ||
497 | case V4L2_CID_MPEG_VIDEO_ASPECT: | ||
498 | old = params->vi_aspect; | ||
499 | if (set && new != V4L2_MPEG_VIDEO_ASPECT_16x9 && | ||
500 | new != V4L2_MPEG_VIDEO_ASPECT_4x3) | ||
501 | return -ERANGE; | ||
502 | if (new != V4L2_MPEG_VIDEO_ASPECT_16x9) | ||
503 | new = V4L2_MPEG_VIDEO_ASPECT_4x3; | ||
504 | params->vi_aspect = new; | ||
505 | break; | ||
506 | case V4L2_CID_MPEG_VIDEO_BITRATE: | ||
507 | old = params->vi_bitrate * 1000; | ||
508 | new = 1000 * (new / 1000); | ||
509 | if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000) | ||
510 | return -ERANGE; | ||
511 | if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000) | ||
512 | new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000; | ||
513 | params->vi_bitrate = new / 1000; | ||
514 | break; | ||
515 | case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: | ||
516 | old = params->vi_bitrate_peak * 1000; | ||
517 | new = 1000 * (new / 1000); | ||
518 | if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000) | ||
519 | return -ERANGE; | ||
520 | if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000) | ||
521 | new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000; | ||
522 | params->vi_bitrate_peak = new / 1000; | ||
523 | break; | ||
524 | case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: | ||
525 | old = params->vi_bitrate_mode; | ||
526 | params->vi_bitrate_mode = new; | ||
527 | break; | ||
528 | default: | ||
529 | return -EINVAL; | ||
530 | } | ||
531 | if (cmd == VIDIOC_G_EXT_CTRLS) | ||
532 | ctrl->value = old; | ||
363 | else | 533 | else |
364 | h->params.au_bitrate.target = 384; | 534 | ctrl->value = new; |
535 | return 0; | ||
365 | } | 536 | } |
366 | 537 | ||
367 | static int saa6752hs_init(struct i2c_client* client) | 538 | static int saa6752hs_init(struct i2c_client* client) |
@@ -489,11 +660,11 @@ static int saa6752hs_init(struct i2c_client* client) | |||
489 | buf[3] = 0x82; | 660 | buf[3] = 0x82; |
490 | buf[4] = 0xB0; | 661 | buf[4] = 0xB0; |
491 | buf[5] = buf2[0]; | 662 | buf[5] = buf2[0]; |
492 | switch(h->params.vi_aspect_ratio) { | 663 | switch(h->params.vi_aspect) { |
493 | case V4L2_MPEG_ASPECT_16_9: | 664 | case V4L2_MPEG_VIDEO_ASPECT_16x9: |
494 | buf[6] = buf2[1] | 0x40; | 665 | buf[6] = buf2[1] | 0x40; |
495 | break; | 666 | break; |
496 | case V4L2_MPEG_ASPECT_4_3: | 667 | case V4L2_MPEG_VIDEO_ASPECT_4x3: |
497 | default: | 668 | default: |
498 | buf[6] = buf2[1] & 0xBF; | 669 | buf[6] = buf2[1] & 0xBF; |
499 | break; | 670 | break; |
@@ -515,6 +686,7 @@ static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind) | |||
515 | return -ENOMEM; | 686 | return -ENOMEM; |
516 | h->client = client_template; | 687 | h->client = client_template; |
517 | h->params = param_defaults; | 688 | h->params = param_defaults; |
689 | h->old_params = old_param_defaults; | ||
518 | h->client.adapter = adap; | 690 | h->client.adapter = adap; |
519 | h->client.addr = addr; | 691 | h->client.addr = addr; |
520 | 692 | ||
@@ -550,20 +722,45 @@ static int | |||
550 | saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) | 722 | saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) |
551 | { | 723 | { |
552 | struct saa6752hs_state *h = i2c_get_clientdata(client); | 724 | struct saa6752hs_state *h = i2c_get_clientdata(client); |
553 | struct v4l2_mpeg_compression *params = arg; | 725 | struct v4l2_ext_controls *ctrls = arg; |
726 | struct v4l2_mpeg_compression *old_params = arg; | ||
727 | struct saa6752hs_mpeg_params params; | ||
554 | int err = 0; | 728 | int err = 0; |
729 | int i; | ||
555 | 730 | ||
556 | switch (cmd) { | 731 | switch (cmd) { |
557 | case VIDIOC_S_MPEGCOMP: | 732 | case VIDIOC_S_MPEGCOMP: |
558 | if (NULL == params) { | 733 | if (NULL == old_params) { |
559 | /* apply settings and start encoder */ | 734 | /* apply settings and start encoder */ |
560 | saa6752hs_init(client); | 735 | saa6752hs_init(client); |
561 | break; | 736 | break; |
562 | } | 737 | } |
563 | saa6752hs_set_params(client, params); | 738 | saa6752hs_old_set_params(client, old_params); |
564 | /* fall through */ | 739 | /* fall through */ |
565 | case VIDIOC_G_MPEGCOMP: | 740 | case VIDIOC_G_MPEGCOMP: |
566 | *params = h->params; | 741 | *old_params = h->old_params; |
742 | break; | ||
743 | case VIDIOC_S_EXT_CTRLS: | ||
744 | if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) | ||
745 | return -EINVAL; | ||
746 | if (ctrls->count == 0) { | ||
747 | /* apply settings and start encoder */ | ||
748 | saa6752hs_init(client); | ||
749 | break; | ||
750 | } | ||
751 | /* fall through */ | ||
752 | case VIDIOC_TRY_EXT_CTRLS: | ||
753 | case VIDIOC_G_EXT_CTRLS: | ||
754 | if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) | ||
755 | return -EINVAL; | ||
756 | params = h->params; | ||
757 | for (i = 0; i < ctrls->count; i++) { | ||
758 | if ((err = handle_ctrl(¶ms, ctrls->controls + i, cmd))) { | ||
759 | ctrls->error_idx = i; | ||
760 | return err; | ||
761 | } | ||
762 | } | ||
763 | h->params = params; | ||
567 | break; | 764 | break; |
568 | case VIDIOC_G_FMT: | 765 | case VIDIOC_G_FMT: |
569 | { | 766 | { |