diff options
author | vdb128@picaros.org <vdb128@picaros.org> | 2008-08-30 17:26:39 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-10-12 07:36:57 -0400 |
commit | e784bfb93c155ba4b354452c69ac02a29d336d97 (patch) | |
tree | da8d1a7ec7803cef22510c505307fd222f05d912 /drivers/media/video/pvrusb2/pvrusb2-hdw.c | |
parent | fe15f13679bf52bb5c8acb8b4847e6d73ba62c17 (diff) |
V4L/DVB (8896): pvrusb2: Implement crop support
Implement pvrusb2 driver plumbing to support cropping. Submitted by a
pvrusb2 user.
Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/pvrusb2/pvrusb2-hdw.c')
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-hdw.c | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index a7d636f3f9b6..68f4315201a5 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c | |||
@@ -402,6 +402,52 @@ static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v) | |||
402 | return 0; | 402 | return 0; |
403 | } | 403 | } |
404 | 404 | ||
405 | static int ctrl_cropl_min_get(struct pvr2_ctrl *cptr, int *left) | ||
406 | { | ||
407 | struct v4l2_cropcap *cap = &cptr->hdw->cropcap; | ||
408 | if (cap->bounds.width > 0) { | ||
409 | /* This statement is present purely to shut up | ||
410 | checkpatch.pl */ | ||
411 | *left = cap->bounds.left - cap->defrect.left; | ||
412 | } else { | ||
413 | /* This statement is present purely to shut up | ||
414 | checkpatch.pl */ | ||
415 | *left = -119; | ||
416 | } | ||
417 | return 0; | ||
418 | } | ||
419 | |||
420 | static int ctrl_cropl_max_get(struct pvr2_ctrl *cptr, int *left) | ||
421 | { | ||
422 | struct v4l2_cropcap *cap = &cptr->hdw->cropcap; | ||
423 | if (cap->bounds.width > 0) { | ||
424 | *left = cap->bounds.left + cap->bounds.width | ||
425 | - cap->defrect.left; | ||
426 | *left += 3; | ||
427 | *left -= cptr->hdw->cropw_val; | ||
428 | } else { | ||
429 | /* This statement is present purely to shut up | ||
430 | checkpatch.pl */ | ||
431 | *left = 340; | ||
432 | } | ||
433 | return 0; | ||
434 | } | ||
435 | |||
436 | static int ctrl_cropt_min_get(struct pvr2_ctrl *cptr, int *top) | ||
437 | { | ||
438 | struct v4l2_cropcap *cap = &cptr->hdw->cropcap; | ||
439 | if (cap->bounds.height > 0) { | ||
440 | /* This statement is present purely to shut up | ||
441 | checkpatch.pl */ | ||
442 | *top = cap->bounds.top - cap->defrect.top; | ||
443 | } else { | ||
444 | /* This statement is present purely to shut up | ||
445 | checkpatch.pl */ | ||
446 | *top = -19; | ||
447 | } | ||
448 | return 0; | ||
449 | } | ||
450 | |||
405 | static int ctrl_vres_max_get(struct pvr2_ctrl *cptr,int *vp) | 451 | static int ctrl_vres_max_get(struct pvr2_ctrl *cptr,int *vp) |
406 | { | 452 | { |
407 | /* Actual maximum depends on the video standard in effect. */ | 453 | /* Actual maximum depends on the video standard in effect. */ |
@@ -413,6 +459,19 @@ static int ctrl_vres_max_get(struct pvr2_ctrl *cptr,int *vp) | |||
413 | return 0; | 459 | return 0; |
414 | } | 460 | } |
415 | 461 | ||
462 | static int ctrl_cropt_max_get(struct pvr2_ctrl *cptr, int *top) | ||
463 | { | ||
464 | struct v4l2_cropcap *cap = &cptr->hdw->cropcap; | ||
465 | if (cap->bounds.height > 0) { | ||
466 | *top = cap->bounds.top + cap->bounds.height - cap->defrect.top; | ||
467 | *top -= cptr->hdw->croph_val; | ||
468 | } else { | ||
469 | ctrl_vres_max_get(cptr, top); | ||
470 | *top -= 32; | ||
471 | } | ||
472 | return 0; | ||
473 | } | ||
474 | |||
416 | static int ctrl_vres_min_get(struct pvr2_ctrl *cptr,int *vp) | 475 | static int ctrl_vres_min_get(struct pvr2_ctrl *cptr,int *vp) |
417 | { | 476 | { |
418 | /* Actual minimum depends on device digitizer type. */ | 477 | /* Actual minimum depends on device digitizer type. */ |
@@ -779,6 +838,10 @@ VCREATE_FUNCS(balance) | |||
779 | VCREATE_FUNCS(bass) | 838 | VCREATE_FUNCS(bass) |
780 | VCREATE_FUNCS(treble) | 839 | VCREATE_FUNCS(treble) |
781 | VCREATE_FUNCS(mute) | 840 | VCREATE_FUNCS(mute) |
841 | VCREATE_FUNCS(cropl) | ||
842 | VCREATE_FUNCS(cropt) | ||
843 | VCREATE_FUNCS(cropw) | ||
844 | VCREATE_FUNCS(croph) | ||
782 | VCREATE_FUNCS(audiomode) | 845 | VCREATE_FUNCS(audiomode) |
783 | VCREATE_FUNCS(res_hor) | 846 | VCREATE_FUNCS(res_hor) |
784 | VCREATE_FUNCS(res_ver) | 847 | VCREATE_FUNCS(res_ver) |
@@ -849,6 +912,39 @@ static const struct pvr2_ctl_info control_defs[] = { | |||
849 | .default_value = 0, | 912 | .default_value = 0, |
850 | DEFREF(mute), | 913 | DEFREF(mute), |
851 | DEFBOOL, | 914 | DEFBOOL, |
915 | }, { | ||
916 | .desc = "Capture left margin", | ||
917 | .name = "crop_left", | ||
918 | .internal_id = PVR2_CID_CROPL, | ||
919 | .default_value = 0, | ||
920 | DEFREF(cropl), | ||
921 | DEFINT(-129, 340), | ||
922 | .get_min_value = ctrl_cropl_min_get, | ||
923 | .get_max_value = ctrl_cropl_max_get, | ||
924 | }, { | ||
925 | .desc = "Capture top margin", | ||
926 | .name = "crop_top", | ||
927 | .internal_id = PVR2_CID_CROPT, | ||
928 | .default_value = 0, | ||
929 | DEFREF(cropt), | ||
930 | DEFINT(-35, 544), | ||
931 | .get_min_value = ctrl_cropt_min_get, | ||
932 | .get_max_value = ctrl_cropt_max_get, | ||
933 | }, { | ||
934 | .desc = "Capture width", | ||
935 | .name = "crop_width", | ||
936 | .internal_id = PVR2_CID_CROPW, | ||
937 | .default_value = 720, | ||
938 | DEFREF(cropw), | ||
939 | DEFINT(388, 849), /* determined empirically, any res_hor>=64 */ | ||
940 | }, { | ||
941 | .desc = "Capture height", | ||
942 | .name = "crop_height", | ||
943 | .internal_id = PVR2_CID_CROPH, | ||
944 | .default_value = 480, | ||
945 | DEFREF(croph), | ||
946 | DEFINT(32, 576), | ||
947 | .get_max_value = ctrl_vres_max_get, | ||
852 | },{ | 948 | },{ |
853 | .desc = "Video Source", | 949 | .desc = "Video Source", |
854 | .name = "input", | 950 | .name = "input", |
@@ -2092,6 +2188,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | |||
2092 | valid_std_mask; | 2188 | valid_std_mask; |
2093 | } | 2189 | } |
2094 | 2190 | ||
2191 | memset(&hdw->cropcap, 0, sizeof hdw->cropcap); | ||
2095 | hdw->eeprom_addr = -1; | 2192 | hdw->eeprom_addr = -1; |
2096 | hdw->unit_number = -1; | 2193 | hdw->unit_number = -1; |
2097 | hdw->v4l_minor_number_video = -1; | 2194 | hdw->v4l_minor_number_video = -1; |
@@ -2528,6 +2625,28 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw) | |||
2528 | /* Can't commit anything until pathway is ok. */ | 2625 | /* Can't commit anything until pathway is ok. */ |
2529 | return 0; | 2626 | return 0; |
2530 | } | 2627 | } |
2628 | /* The broadcast decoder can only scale down, so if | ||
2629 | * res_*_dirty && crop window < output format ==> enlarge crop. | ||
2630 | * | ||
2631 | * The mpeg encoder receives fields of res_hor_val dots and | ||
2632 | * res_ver_val halflines. Limits: hor<=720, ver<=576. | ||
2633 | */ | ||
2634 | if (hdw->res_hor_dirty && hdw->cropw_val < hdw->res_hor_val) { | ||
2635 | hdw->cropw_val = hdw->res_hor_val; | ||
2636 | hdw->cropw_dirty = !0; | ||
2637 | } else if (hdw->cropw_dirty) { | ||
2638 | hdw->res_hor_dirty = !0; /* must rescale */ | ||
2639 | hdw->res_hor_val = min(720, hdw->cropw_val); | ||
2640 | } | ||
2641 | if (hdw->res_ver_dirty && hdw->croph_val < hdw->res_ver_val) { | ||
2642 | hdw->croph_val = hdw->res_ver_val; | ||
2643 | hdw->croph_dirty = !0; | ||
2644 | } else if (hdw->croph_dirty) { | ||
2645 | int nvres = hdw->std_mask_cur & V4L2_STD_525_60 ? 480 : 576; | ||
2646 | hdw->res_ver_dirty = !0; | ||
2647 | hdw->res_ver_val = min(nvres, hdw->croph_val); | ||
2648 | } | ||
2649 | |||
2531 | /* If any of the below has changed, then we can't do the update | 2650 | /* If any of the below has changed, then we can't do the update |
2532 | while the pipeline is running. Pipeline must be paused first | 2651 | while the pipeline is running. Pipeline must be paused first |
2533 | and decoder -> encoder connection be made quiescent before we | 2652 | and decoder -> encoder connection be made quiescent before we |