lkml.org 
[lkml]   [2006]   [Mar]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 023/141] V4L/DVB (3422): Implemented VIDIOC_G_FMT/S_FMT for sliced VBI
    Date
    From: Mauro Carvalho Chehab <mchehab@infradead.org>
    Date: 1138043468 -0200

    - Implemented VIDIOC_G_FMT/S_FMT for sliced VBI
    - VIDIOC_S_FMT now calls a function

    Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
    ---

    diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
    diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
    index e4e82ae..d8d02c4 100644
    --- a/drivers/media/video/em28xx/em28xx-video.c
    +++ b/drivers/media/video/em28xx/em28xx-video.c
    @@ -897,7 +897,6 @@ static int em28xx_set_norm(struct em28xx
    return 0;
    }

    -
    static int em28xx_get_fmt(struct em28xx *dev, struct v4l2_format *format)
    {
    em28xx_videodbg("VIDIOC_G_FMT: type=%s\n",
    @@ -909,7 +908,9 @@ static int em28xx_get_fmt(struct em28xx
    "V4L2_BUF_TYPE_SLICED_VBI_CAPTURE " :
    "not supported");

    - if (format->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
    + switch (format->type) {
    + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
    + {
    format->fmt.pix.width = dev->width;
    format->fmt.pix.height = dev->height;
    format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
    @@ -920,12 +921,161 @@ static int em28xx_get_fmt(struct em28xx

    em28xx_videodbg("VIDIOC_G_FMT: %dx%d\n", dev->width,
    dev->height);
    - return 0;
    + break;
    }

    - return -EINVAL;
    + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
    + {
    + format->fmt.sliced.service_set=0;
    +
    + em28xx_i2c_call_clients(dev,VIDIOC_G_FMT,format);
    +
    + if (format->fmt.sliced.service_set==0)
    + return -EINVAL;
    +
    + break;
    + }
    +
    + default:
    + return -EINVAL;
    + }
    + return (0);
    }

    +static int em28xx_set_fmt(struct em28xx *dev, unsigned int cmd, struct v4l2_format *format)
    +{
    + u32 i;
    + int ret = 0;
    + int width = format->fmt.pix.width;
    + int height = format->fmt.pix.height;
    + unsigned int hscale, vscale;
    + unsigned int maxh, maxw;
    +
    + maxw = norm_maxw(dev);
    + maxh = norm_maxh(dev);
    +
    + em28xx_videodbg("%s: type=%s\n",
    + cmd == VIDIOC_TRY_FMT ?
    + "VIDIOC_TRY_FMT" : "VIDIOC_S_FMT",
    + format->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ?
    + "V4L2_BUF_TYPE_VIDEO_CAPTURE" :
    + format->type == V4L2_BUF_TYPE_VBI_CAPTURE ?
    + "V4L2_BUF_TYPE_VBI_CAPTURE " :
    + "not supported");
    +
    + if (format->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
    + em28xx_i2c_call_clients(dev,VIDIOC_G_FMT,format);
    +
    + if (format->fmt.sliced.service_set==0)
    + return -EINVAL;
    +
    + return 0;
    + }
    +
    +
    + if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
    + return -EINVAL;
    +
    + em28xx_videodbg("%s: requested %dx%d\n",
    + cmd == VIDIOC_TRY_FMT ?
    + "VIDIOC_TRY_FMT" : "VIDIOC_S_FMT",
    + format->fmt.pix.width, format->fmt.pix.height);
    +
    + /* FIXME: Move some code away from here */
    + /* width must even because of the YUYV format */
    + /* height must be even because of interlacing */
    + height &= 0xfffe;
    + width &= 0xfffe;
    +
    + if (height < 32)
    + height = 32;
    + if (height > maxh)
    + height = maxh;
    + if (width < 48)
    + width = 48;
    + if (width > maxw)
    + width = maxw;
    +
    + if(dev->is_em2800){
    + /* the em2800 can only scale down to 50% */
    + if(height % (maxh / 2))
    + height=maxh;
    + if(width % (maxw / 2))
    + width=maxw;
    + /* according to empiatech support */
    + /* the MaxPacketSize is to small to support */
    + /* framesizes larger than 640x480 @ 30 fps */
    + /* or 640x576 @ 25 fps. As this would cut */
    + /* of a part of the image we prefer */
    + /* 360x576 or 360x480 for now */
    + if(width == maxw && height == maxh)
    + width /= 2;
    + }
    +
    + if ((hscale =
    + (((unsigned long)maxw) << 12) / width - 4096L) >=
    + 0x4000)
    + hscale = 0x3fff;
    + width =
    + (((unsigned long)maxw) << 12) / (hscale + 4096L);
    +
    + if ((vscale =
    + (((unsigned long)maxh) << 12) / height - 4096L) >=
    + 0x4000)
    + vscale = 0x3fff;
    + height =
    + (((unsigned long)maxh) << 12) / (vscale + 4096L);
    +
    + format->fmt.pix.width = width;
    + format->fmt.pix.height = height;
    + format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
    + format->fmt.pix.bytesperline = width * 2;
    + format->fmt.pix.sizeimage = width * 2 * height;
    + format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
    + format->fmt.pix.field = V4L2_FIELD_INTERLACED;
    +
    + em28xx_videodbg("%s: returned %dx%d (%d, %d)\n",
    + cmd ==
    + VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
    + "VIDIOC_S_FMT", format->fmt.pix.width,
    + format->fmt.pix.height, hscale, vscale);
    +
    + if (cmd == VIDIOC_TRY_FMT)
    + return 0;
    +
    + for (i = 0; i < dev->num_frames; i++)
    + if (dev->frame[i].vma_use_count) {
    + em28xx_videodbg("VIDIOC_S_FMT failed. "
    + "Unmap the buffers first.\n");
    + return -EINVAL;
    + }
    +
    + /* stop io in case it is already in progress */
    + if (dev->stream == STREAM_ON) {
    + em28xx_videodbg("VIDIOC_SET_FMT: interupting stream\n");
    + if ((ret = em28xx_stream_interrupt(dev)))
    + return ret;
    + }
    +
    + em28xx_release_buffers(dev);
    + dev->io = IO_NONE;
    +
    + /* set new image size */
    + dev->width = width;
    + dev->height = height;
    + dev->frame_size = dev->width * dev->height * 2;
    + dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */
    + dev->bytesperline = dev->width * 2;
    + dev->hscale = hscale;
    + dev->vscale = vscale;
    + em28xx_uninit_isoc(dev);
    + em28xx_set_alternate(dev);
    + em28xx_capture_start(dev, 1);
    + em28xx_resolution_set(dev);
    + em28xx_init_isoc(dev);
    +
    + return 0;
    +}

    /*
    * em28xx_v4l2_do_ioctl()
    @@ -983,24 +1133,6 @@ static int em28xx_do_ioctl(struct inode

    em28xx_set_norm(dev, dev->width, dev->height);

    -/*
    - dev->width=norm_maxw(dev);
    - dev->height=norm_maxh(dev);
    - dev->frame_size=dev->width*dev->height*2;
    - dev->field_size=dev->frame_size>>1;
    - dev->bytesperline=dev->width*2;
    - dev->hscale=0;
    - dev->vscale=0;
    -
    - em28xx_resolution_set(dev);
    -*/
    -/*
    - em28xx_uninit_isoc(dev);
    - em28xx_set_alternate(dev);
    - em28xx_capture_start(dev, 1);
    - em28xx_resolution_set(dev);
    - em28xx_init_isoc(dev);
    -*/
    em28xx_i2c_call_clients(dev, DECODER_SET_NORM,
    &tvnorms[i].mode);
    em28xx_i2c_call_clients(dev, VIDIOC_S_STD,
    @@ -1396,138 +1528,8 @@ static int em28xx_video_do_ioctl(struct

    case VIDIOC_TRY_FMT:
    case VIDIOC_S_FMT:
    - {
    - struct v4l2_format *format = arg;
    - u32 i;
    - int ret = 0;
    - int width = format->fmt.pix.width;
    - int height = format->fmt.pix.height;
    - unsigned int hscale, vscale;
    - unsigned int maxh, maxw;
    -
    - maxw = norm_maxw(dev);
    - maxh = norm_maxh(dev);
    -
    -/* int both_fields; */
    -
    - em28xx_videodbg("%s: type=%s\n",
    - cmd ==
    - VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
    - "VIDIOC_S_FMT",
    - format->type ==
    - V4L2_BUF_TYPE_VIDEO_CAPTURE ?
    - "V4L2_BUF_TYPE_VIDEO_CAPTURE" : format->type ==
    - V4L2_BUF_TYPE_VBI_CAPTURE ?
    - "V4L2_BUF_TYPE_VBI_CAPTURE " :
    - "not supported");
    -
    - if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
    - return -EINVAL;
    -
    - em28xx_videodbg("%s: requested %dx%d\n",
    - cmd ==
    - VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
    - "VIDIOC_S_FMT", format->fmt.pix.width,
    - format->fmt.pix.height);
    -
    - /* FIXME: Move some code away from here */
    - /* width must even because of the YUYV format */
    - /* height must be even because of interlacing */
    - height &= 0xfffe;
    - width &= 0xfffe;
    -
    - if (height < 32)
    - height = 32;
    - if (height > maxh)
    - height = maxh;
    - if (width < 48)
    - width = 48;
    - if (width > maxw)
    - width = maxw;
    -
    - if(dev->is_em2800){
    - /* the em2800 can only scale down to 50% */
    - if(height % (maxh / 2))
    - height=maxh;
    - if(width % (maxw / 2))
    - width=maxw;
    - /* according to empiatech support */
    - /* the MaxPacketSize is to small to support */
    - /* framesizes larger than 640x480 @ 30 fps */
    - /* or 640x576 @ 25 fps. As this would cut */
    - /* of a part of the image we prefer */
    - /* 360x576 or 360x480 for now */
    - if(width == maxw && height == maxh)
    - width /= 2;
    - }
    -
    - if ((hscale =
    - (((unsigned long)maxw) << 12) / width - 4096L) >=
    - 0x4000)
    - hscale = 0x3fff;
    - width =
    - (((unsigned long)maxw) << 12) / (hscale + 4096L);
    -
    - if ((vscale =
    - (((unsigned long)maxh) << 12) / height - 4096L) >=
    - 0x4000)
    - vscale = 0x3fff;
    - height =
    - (((unsigned long)maxh) << 12) / (vscale + 4096L);
    -
    - format->fmt.pix.width = width;
    - format->fmt.pix.height = height;
    - format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
    - format->fmt.pix.bytesperline = width * 2;
    - format->fmt.pix.sizeimage = width * 2 * height;
    - format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
    - format->fmt.pix.field = V4L2_FIELD_INTERLACED;
    -
    - em28xx_videodbg("%s: returned %dx%d (%d, %d)\n",
    - cmd ==
    - VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
    - "VIDIOC_S_FMT", format->fmt.pix.width,
    - format->fmt.pix.height, hscale, vscale);
    -
    - if (cmd == VIDIOC_TRY_FMT)
    - return 0;
    -
    - for (i = 0; i < dev->num_frames; i++)
    - if (dev->frame[i].vma_use_count) {
    - em28xx_videodbg("VIDIOC_S_FMT failed. "
    - "Unmap the buffers first.\n");
    - return -EINVAL;
    - }
    -
    - /* stop io in case it is already in progress */
    - if (dev->stream == STREAM_ON) {
    - em28xx_videodbg("VIDIOC_SET_FMT: interupting stream\n");
    - if ((ret = em28xx_stream_interrupt(dev)))
    - return ret;
    - }
    -
    - em28xx_release_buffers(dev);
    - dev->io = IO_NONE;
    -
    - /* set new image size */
    - dev->width = width;
    - dev->height = height;
    - dev->frame_size = dev->width * dev->height * 2;
    - dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */
    - dev->bytesperline = dev->width * 2;
    - dev->hscale = hscale;
    - dev->vscale = vscale;
    -/* dev->both_fileds = both_fileds; */
    - em28xx_uninit_isoc(dev);
    - em28xx_set_alternate(dev);
    - em28xx_capture_start(dev, 1);
    - em28xx_resolution_set(dev);
    - em28xx_init_isoc(dev);
    -
    - return 0;
    - }
    + return em28xx_set_fmt(dev, cmd, (struct v4l2_format *)arg);

    - /* --- streaming capture ------------------------------------- */
    case VIDIOC_REQBUFS:
    {
    struct v4l2_requestbuffers *rb = arg;
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2006-03-20 16:22    [W:5.104 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site