diff options
Diffstat (limited to 'drivers/media/pci/ivtv/ivtv-ioctl.c')
-rw-r--r-- | drivers/media/pci/ivtv/ivtv-ioctl.c | 159 |
1 files changed, 99 insertions, 60 deletions
diff --git a/drivers/media/pci/ivtv/ivtv-ioctl.c b/drivers/media/pci/ivtv/ivtv-ioctl.c index 4d8ee18c3feb..6fe6c4a0e858 100644 --- a/drivers/media/pci/ivtv/ivtv-ioctl.c +++ b/drivers/media/pci/ivtv/ivtv-ioctl.c | |||
@@ -448,9 +448,12 @@ static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *f | |||
448 | static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) | 448 | static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) |
449 | { | 449 | { |
450 | struct ivtv *itv = fh2id(fh)->itv; | 450 | struct ivtv *itv = fh2id(fh)->itv; |
451 | struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; | ||
451 | struct v4l2_window *winfmt = &fmt->fmt.win; | 452 | struct v4l2_window *winfmt = &fmt->fmt.win; |
452 | 453 | ||
453 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | 454 | if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) |
455 | return -EINVAL; | ||
456 | if (!itv->osd_video_pbase) | ||
454 | return -EINVAL; | 457 | return -EINVAL; |
455 | winfmt->chromakey = itv->osd_chroma_key; | 458 | winfmt->chromakey = itv->osd_chroma_key; |
456 | winfmt->global_alpha = itv->osd_global_alpha; | 459 | winfmt->global_alpha = itv->osd_global_alpha; |
@@ -555,10 +558,13 @@ static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format | |||
555 | static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) | 558 | static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) |
556 | { | 559 | { |
557 | struct ivtv *itv = fh2id(fh)->itv; | 560 | struct ivtv *itv = fh2id(fh)->itv; |
561 | struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; | ||
558 | u32 chromakey = fmt->fmt.win.chromakey; | 562 | u32 chromakey = fmt->fmt.win.chromakey; |
559 | u8 global_alpha = fmt->fmt.win.global_alpha; | 563 | u8 global_alpha = fmt->fmt.win.global_alpha; |
560 | 564 | ||
561 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | 565 | if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) |
566 | return -EINVAL; | ||
567 | if (!itv->osd_video_pbase) | ||
562 | return -EINVAL; | 568 | return -EINVAL; |
563 | ivtv_g_fmt_vid_out_overlay(file, fh, fmt); | 569 | ivtv_g_fmt_vid_out_overlay(file, fh, fmt); |
564 | fmt->fmt.win.chromakey = chromakey; | 570 | fmt->fmt.win.chromakey = chromakey; |
@@ -741,6 +747,11 @@ static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vc | |||
741 | snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev)); | 747 | snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev)); |
742 | vcap->capabilities = itv->v4l2_cap | V4L2_CAP_DEVICE_CAPS; | 748 | vcap->capabilities = itv->v4l2_cap | V4L2_CAP_DEVICE_CAPS; |
743 | vcap->device_caps = s->caps; | 749 | vcap->device_caps = s->caps; |
750 | if ((s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY) && | ||
751 | !itv->osd_video_pbase) { | ||
752 | vcap->capabilities &= ~V4L2_CAP_VIDEO_OUTPUT_OVERLAY; | ||
753 | vcap->device_caps &= ~V4L2_CAP_VIDEO_OUTPUT_OVERLAY; | ||
754 | } | ||
744 | return 0; | 755 | return 0; |
745 | } | 756 | } |
746 | 757 | ||
@@ -816,80 +827,103 @@ static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropca | |||
816 | { | 827 | { |
817 | struct ivtv_open_id *id = fh2id(fh); | 828 | struct ivtv_open_id *id = fh2id(fh); |
818 | struct ivtv *itv = id->itv; | 829 | struct ivtv *itv = id->itv; |
819 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
820 | int streamtype; | ||
821 | |||
822 | streamtype = id->type; | ||
823 | 830 | ||
824 | if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) | ||
825 | return -EINVAL; | ||
826 | cropcap->bounds.top = cropcap->bounds.left = 0; | ||
827 | cropcap->bounds.width = 720; | ||
828 | if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | 831 | if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { |
829 | cropcap->bounds.height = itv->is_50hz ? 576 : 480; | ||
830 | cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10; | 832 | cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10; |
831 | cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11; | 833 | cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11; |
832 | } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { | 834 | } else if (cropcap->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { |
833 | if (yi->track_osd) { | ||
834 | cropcap->bounds.width = yi->osd_full_w; | ||
835 | cropcap->bounds.height = yi->osd_full_h; | ||
836 | } else { | ||
837 | cropcap->bounds.width = 720; | ||
838 | cropcap->bounds.height = | ||
839 | itv->is_out_50hz ? 576 : 480; | ||
840 | } | ||
841 | cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10; | 835 | cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10; |
842 | cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11; | 836 | cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11; |
843 | } else { | 837 | } else { |
844 | cropcap->bounds.height = itv->is_out_50hz ? 576 : 480; | 838 | return -EINVAL; |
845 | cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10; | ||
846 | cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11; | ||
847 | } | 839 | } |
848 | cropcap->defrect = cropcap->bounds; | ||
849 | return 0; | 840 | return 0; |
850 | } | 841 | } |
851 | 842 | ||
852 | static int ivtv_s_crop(struct file *file, void *fh, const struct v4l2_crop *crop) | 843 | static int ivtv_s_selection(struct file *file, void *fh, |
844 | struct v4l2_selection *sel) | ||
853 | { | 845 | { |
854 | struct ivtv_open_id *id = fh2id(fh); | 846 | struct ivtv_open_id *id = fh2id(fh); |
855 | struct ivtv *itv = id->itv; | 847 | struct ivtv *itv = id->itv; |
856 | struct yuv_playback_info *yi = &itv->yuv_info; | 848 | struct yuv_playback_info *yi = &itv->yuv_info; |
857 | int streamtype; | 849 | struct v4l2_rect r = { 0, 0, 720, 0 }; |
850 | int streamtype = id->type; | ||
858 | 851 | ||
859 | streamtype = id->type; | 852 | if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT || |
853 | !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | ||
854 | return -EINVAL; | ||
860 | 855 | ||
861 | if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && | 856 | if (sel->target != V4L2_SEL_TGT_COMPOSE) |
862 | (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { | ||
863 | if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { | ||
864 | yi->main_rect = crop->c; | ||
865 | return 0; | ||
866 | } else { | ||
867 | if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4, | ||
868 | crop->c.width, crop->c.height, crop->c.left, crop->c.top)) { | ||
869 | itv->main_rect = crop->c; | ||
870 | return 0; | ||
871 | } | ||
872 | } | ||
873 | return -EINVAL; | 857 | return -EINVAL; |
858 | |||
859 | |||
860 | if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT || | ||
861 | !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | ||
862 | return -EINVAL; | ||
863 | |||
864 | r.height = itv->is_out_50hz ? 576 : 480; | ||
865 | if (streamtype == IVTV_DEC_STREAM_TYPE_YUV && yi->track_osd) { | ||
866 | r.width = yi->osd_full_w; | ||
867 | r.height = yi->osd_full_h; | ||
868 | } | ||
869 | sel->r.width = clamp(sel->r.width, 16U, r.width); | ||
870 | sel->r.height = clamp(sel->r.height, 16U, r.height); | ||
871 | sel->r.left = clamp_t(unsigned, sel->r.left, 0, r.width - sel->r.width); | ||
872 | sel->r.top = clamp_t(unsigned, sel->r.top, 0, r.height - sel->r.height); | ||
873 | |||
874 | if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { | ||
875 | yi->main_rect = sel->r; | ||
876 | return 0; | ||
877 | } | ||
878 | if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4, | ||
879 | sel->r.width, sel->r.height, sel->r.left, sel->r.top)) { | ||
880 | itv->main_rect = sel->r; | ||
881 | return 0; | ||
874 | } | 882 | } |
875 | return -EINVAL; | 883 | return -EINVAL; |
876 | } | 884 | } |
877 | 885 | ||
878 | static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop) | 886 | static int ivtv_g_selection(struct file *file, void *fh, |
887 | struct v4l2_selection *sel) | ||
879 | { | 888 | { |
880 | struct ivtv_open_id *id = fh2id(fh); | 889 | struct ivtv_open_id *id = fh2id(fh); |
881 | struct ivtv *itv = id->itv; | 890 | struct ivtv *itv = id->itv; |
882 | struct yuv_playback_info *yi = &itv->yuv_info; | 891 | struct yuv_playback_info *yi = &itv->yuv_info; |
883 | int streamtype; | 892 | struct v4l2_rect r = { 0, 0, 720, 0 }; |
893 | int streamtype = id->type; | ||
894 | |||
895 | if (sel->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
896 | switch (sel->target) { | ||
897 | case V4L2_SEL_TGT_CROP_DEFAULT: | ||
898 | case V4L2_SEL_TGT_CROP_BOUNDS: | ||
899 | sel->r.top = sel->r.left = 0; | ||
900 | sel->r.width = 720; | ||
901 | sel->r.height = itv->is_50hz ? 576 : 480; | ||
902 | return 0; | ||
903 | default: | ||
904 | return -EINVAL; | ||
905 | } | ||
906 | } | ||
884 | 907 | ||
885 | streamtype = id->type; | 908 | if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT || |
909 | !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | ||
910 | return -EINVAL; | ||
886 | 911 | ||
887 | if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && | 912 | switch (sel->target) { |
888 | (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { | 913 | case V4L2_SEL_TGT_COMPOSE: |
889 | if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) | 914 | if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) |
890 | crop->c = yi->main_rect; | 915 | sel->r = yi->main_rect; |
891 | else | 916 | else |
892 | crop->c = itv->main_rect; | 917 | sel->r = itv->main_rect; |
918 | return 0; | ||
919 | case V4L2_SEL_TGT_COMPOSE_DEFAULT: | ||
920 | case V4L2_SEL_TGT_COMPOSE_BOUNDS: | ||
921 | r.height = itv->is_out_50hz ? 576 : 480; | ||
922 | if (streamtype == IVTV_DEC_STREAM_TYPE_YUV && yi->track_osd) { | ||
923 | r.width = yi->osd_full_w; | ||
924 | r.height = yi->osd_full_h; | ||
925 | } | ||
926 | sel->r = r; | ||
893 | return 0; | 927 | return 0; |
894 | } | 928 | } |
895 | return -EINVAL; | 929 | return -EINVAL; |
@@ -987,7 +1021,7 @@ int ivtv_s_input(struct file *file, void *fh, unsigned int inp) | |||
987 | else | 1021 | else |
988 | std = V4L2_STD_ALL; | 1022 | std = V4L2_STD_ALL; |
989 | for (i = 0; i <= IVTV_ENC_STREAM_TYPE_VBI; i++) | 1023 | for (i = 0; i <= IVTV_ENC_STREAM_TYPE_VBI; i++) |
990 | itv->streams[i].vdev->tvnorms = std; | 1024 | itv->streams[i].vdev.tvnorms = std; |
991 | 1025 | ||
992 | /* prevent others from messing with the streams until | 1026 | /* prevent others from messing with the streams until |
993 | we're finished changing inputs. */ | 1027 | we're finished changing inputs. */ |
@@ -1038,7 +1072,7 @@ static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency * | |||
1038 | struct ivtv *itv = fh2id(fh)->itv; | 1072 | struct ivtv *itv = fh2id(fh)->itv; |
1039 | struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; | 1073 | struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; |
1040 | 1074 | ||
1041 | if (s->vdev->vfl_dir) | 1075 | if (s->vdev.vfl_dir) |
1042 | return -ENOTTY; | 1076 | return -ENOTTY; |
1043 | if (vf->tuner != 0) | 1077 | if (vf->tuner != 0) |
1044 | return -EINVAL; | 1078 | return -EINVAL; |
@@ -1052,7 +1086,7 @@ int ivtv_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *v | |||
1052 | struct ivtv *itv = fh2id(fh)->itv; | 1086 | struct ivtv *itv = fh2id(fh)->itv; |
1053 | struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; | 1087 | struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; |
1054 | 1088 | ||
1055 | if (s->vdev->vfl_dir) | 1089 | if (s->vdev.vfl_dir) |
1056 | return -ENOTTY; | 1090 | return -ENOTTY; |
1057 | if (vf->tuner != 0) | 1091 | if (vf->tuner != 0) |
1058 | return -EINVAL; | 1092 | return -EINVAL; |
@@ -1340,6 +1374,7 @@ static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder | |||
1340 | static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) | 1374 | static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) |
1341 | { | 1375 | { |
1342 | struct ivtv *itv = fh2id(fh)->itv; | 1376 | struct ivtv *itv = fh2id(fh)->itv; |
1377 | struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; | ||
1343 | u32 data[CX2341X_MBOX_MAX_DATA]; | 1378 | u32 data[CX2341X_MBOX_MAX_DATA]; |
1344 | struct yuv_playback_info *yi = &itv->yuv_info; | 1379 | struct yuv_playback_info *yi = &itv->yuv_info; |
1345 | 1380 | ||
@@ -1363,10 +1398,10 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) | |||
1363 | 0, | 1398 | 0, |
1364 | }; | 1399 | }; |
1365 | 1400 | ||
1366 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) | 1401 | if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) |
1367 | return -EINVAL; | 1402 | return -ENOTTY; |
1368 | if (!itv->osd_video_pbase) | 1403 | if (!itv->osd_video_pbase) |
1369 | return -EINVAL; | 1404 | return -ENOTTY; |
1370 | 1405 | ||
1371 | fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY | | 1406 | fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY | |
1372 | V4L2_FBUF_CAP_GLOBAL_ALPHA; | 1407 | V4L2_FBUF_CAP_GLOBAL_ALPHA; |
@@ -1427,12 +1462,13 @@ static int ivtv_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffe | |||
1427 | { | 1462 | { |
1428 | struct ivtv_open_id *id = fh2id(fh); | 1463 | struct ivtv_open_id *id = fh2id(fh); |
1429 | struct ivtv *itv = id->itv; | 1464 | struct ivtv *itv = id->itv; |
1465 | struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; | ||
1430 | struct yuv_playback_info *yi = &itv->yuv_info; | 1466 | struct yuv_playback_info *yi = &itv->yuv_info; |
1431 | 1467 | ||
1432 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) | 1468 | if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) |
1433 | return -EINVAL; | 1469 | return -ENOTTY; |
1434 | if (!itv->osd_video_pbase) | 1470 | if (!itv->osd_video_pbase) |
1435 | return -EINVAL; | 1471 | return -ENOTTY; |
1436 | 1472 | ||
1437 | itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0; | 1473 | itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0; |
1438 | itv->osd_local_alpha_state = | 1474 | itv->osd_local_alpha_state = |
@@ -1447,9 +1483,12 @@ static int ivtv_overlay(struct file *file, void *fh, unsigned int on) | |||
1447 | { | 1483 | { |
1448 | struct ivtv_open_id *id = fh2id(fh); | 1484 | struct ivtv_open_id *id = fh2id(fh); |
1449 | struct ivtv *itv = id->itv; | 1485 | struct ivtv *itv = id->itv; |
1486 | struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; | ||
1450 | 1487 | ||
1451 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) | 1488 | if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) |
1452 | return -EINVAL; | 1489 | return -ENOTTY; |
1490 | if (!itv->osd_video_pbase) | ||
1491 | return -ENOTTY; | ||
1453 | 1492 | ||
1454 | ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0); | 1493 | ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0); |
1455 | 1494 | ||
@@ -1547,7 +1586,7 @@ static int ivtv_log_status(struct file *file, void *fh) | |||
1547 | for (i = 0; i < IVTV_MAX_STREAMS; i++) { | 1586 | for (i = 0; i < IVTV_MAX_STREAMS; i++) { |
1548 | struct ivtv_stream *s = &itv->streams[i]; | 1587 | struct ivtv_stream *s = &itv->streams[i]; |
1549 | 1588 | ||
1550 | if (s->vdev == NULL || s->buffers == 0) | 1589 | if (s->vdev.v4l2_dev == NULL || s->buffers == 0) |
1551 | continue; | 1590 | continue; |
1552 | IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags, | 1591 | IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags, |
1553 | (s->buffers - s->q_free.buffers) * 100 / s->buffers, | 1592 | (s->buffers - s->q_free.buffers) * 100 / s->buffers, |
@@ -1837,8 +1876,8 @@ static const struct v4l2_ioctl_ops ivtv_ioctl_ops = { | |||
1837 | .vidioc_enum_output = ivtv_enum_output, | 1876 | .vidioc_enum_output = ivtv_enum_output, |
1838 | .vidioc_enumaudout = ivtv_enumaudout, | 1877 | .vidioc_enumaudout = ivtv_enumaudout, |
1839 | .vidioc_cropcap = ivtv_cropcap, | 1878 | .vidioc_cropcap = ivtv_cropcap, |
1840 | .vidioc_s_crop = ivtv_s_crop, | 1879 | .vidioc_s_selection = ivtv_s_selection, |
1841 | .vidioc_g_crop = ivtv_g_crop, | 1880 | .vidioc_g_selection = ivtv_g_selection, |
1842 | .vidioc_g_input = ivtv_g_input, | 1881 | .vidioc_g_input = ivtv_g_input, |
1843 | .vidioc_s_input = ivtv_s_input, | 1882 | .vidioc_s_input = ivtv_s_input, |
1844 | .vidioc_g_output = ivtv_g_output, | 1883 | .vidioc_g_output = ivtv_g_output, |