aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pvrusb2/pvrusb2-hdw.c
diff options
context:
space:
mode:
authorvdb128@picaros.org <vdb128@picaros.org>2008-08-30 17:26:39 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-10-12 07:36:57 -0400
commite784bfb93c155ba4b354452c69ac02a29d336d97 (patch)
treeda8d1a7ec7803cef22510c505307fd222f05d912 /drivers/media/video/pvrusb2/pvrusb2-hdw.c
parentfe15f13679bf52bb5c8acb8b4847e6d73ba62c17 (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.c119
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
405static 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
420static 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
436static 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
405static int ctrl_vres_max_get(struct pvr2_ctrl *cptr,int *vp) 451static 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
462static 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
416static int ctrl_vres_min_get(struct pvr2_ctrl *cptr,int *vp) 475static 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)
779VCREATE_FUNCS(bass) 838VCREATE_FUNCS(bass)
780VCREATE_FUNCS(treble) 839VCREATE_FUNCS(treble)
781VCREATE_FUNCS(mute) 840VCREATE_FUNCS(mute)
841VCREATE_FUNCS(cropl)
842VCREATE_FUNCS(cropt)
843VCREATE_FUNCS(cropw)
844VCREATE_FUNCS(croph)
782VCREATE_FUNCS(audiomode) 845VCREATE_FUNCS(audiomode)
783VCREATE_FUNCS(res_hor) 846VCREATE_FUNCS(res_hor)
784VCREATE_FUNCS(res_ver) 847VCREATE_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