From 2392009ea8bfdab6078943ca39f6a5223e557f18 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 17 May 2007 11:41:44 +0200 Subject: Adding new fields to v4l2_pix_format broke the ABI, reverted that change From: Hans Verkuil Reverted the change to struct v4l2_pix_format. I completely missed that this struct was used by existing ioctls so that changing it broke the ABI. I will have to think of another way of setting the top/left coordinates but for now this change is reverted to preserve compatibility. Signed-off-by: Hans Verkuil --- linux/drivers/media/video/ivtv/ivtv-ioctl.c | 23 +++++++++++++++++++++++ linux/include/linux/videodev2.h | 2 -- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/linux/drivers/media/video/ivtv/ivtv-ioctl.c b/linux/drivers/media/video/ivtv/ivtv-ioctl.c index f29c55d3b..5b799f016 100644 --- a/linux/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/linux/drivers/media/video/ivtv/ivtv-ioctl.c @@ -362,8 +362,12 @@ static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fm case V4L2_BUF_TYPE_VIDEO_OUTPUT: if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) return -EINVAL; +#if 0 + /* Temporarily removed until a better solution is in place that does not + break the ABI */ fmt->fmt.pix.left = itv->main_rect.left; fmt->fmt.pix.top = itv->main_rect.top; +#endif fmt->fmt.pix.width = itv->main_rect.width; fmt->fmt.pix.height = itv->main_rect.height; fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; @@ -402,8 +406,12 @@ static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fm break; case V4L2_BUF_TYPE_VIDEO_CAPTURE: +#if 0 + /* Temporarily removed until a better solution is in place that does not + break the ABI */ fmt->fmt.pix.left = 0; fmt->fmt.pix.top = 0; +#endif fmt->fmt.pix.width = itv->params.width; fmt->fmt.pix.height = itv->params.height; fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; @@ -498,15 +506,26 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype, if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) return -EINVAL; field = fmt->fmt.pix.field; +#if 0 + /* Temporarily removed until a better solution is in place that does not + break the ABI */ r.top = fmt->fmt.pix.top; r.left = fmt->fmt.pix.left; +#else + r.top = 0; + r.left = 0; +#endif r.width = fmt->fmt.pix.width; r.height = fmt->fmt.pix.height; ivtv_get_fmt(itv, streamtype, fmt); if (itv->output_mode != OUT_UDMA_YUV) { /* TODO: would setting the rect also be valid for this mode? */ +#if 0 + /* Temporarily removed until a better solution is in place that does not + break the ABI */ fmt->fmt.pix.top = r.top; fmt->fmt.pix.left = r.left; +#endif fmt->fmt.pix.width = r.width; fmt->fmt.pix.height = r.height; } @@ -1153,8 +1172,12 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void fb->fmt.pixelformat = itv->osd_pixelformat; fb->fmt.width = itv->osd_rect.width; fb->fmt.height = itv->osd_rect.height; +#if 0 + /* Temporarily removed until a better solution is in place that does not + break the ABI */ fb->fmt.left = itv->osd_rect.left; fb->fmt.top = itv->osd_rect.top; +#endif fb->base = (void *)itv->osd_video_pbase; if (itv->osd_global_alpha_state) fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; diff --git a/linux/include/linux/videodev2.h b/linux/include/linux/videodev2.h index 76af1e16a..8e46a2029 100644 --- a/linux/include/linux/videodev2.h +++ b/linux/include/linux/videodev2.h @@ -267,8 +267,6 @@ struct v4l2_pix_format __u32 sizeimage; enum v4l2_colorspace colorspace; __u32 priv; /* private data, depends on pixelformat */ - __u32 left; /* only valid if V4L2_CAP_VIDEO_OUTPUT_POS is set */ - __u32 top; /* only valid if V4L2_CAP_VIDEO_OUTPUT_POS is set */ }; /* Pixel format FOURCC depth Description */ -- cgit v1.2.3 From 6177f63f02997cea4023c9de58370ae85dd0a51a Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 17 May 2007 11:52:32 +0200 Subject: Autodetect new PVR150 low profile cards. From: Hans Verkuil Signed-off-by: Hans Verkuil --- linux/drivers/media/video/ivtv/ivtv-driver.c | 1 + 1 file changed, 1 insertion(+) diff --git a/linux/drivers/media/video/ivtv/ivtv-driver.c b/linux/drivers/media/video/ivtv/ivtv-driver.c index 8fbc34db5..e0f6d4363 100644 --- a/linux/drivers/media/video/ivtv/ivtv-driver.c +++ b/linux/drivers/media/video/ivtv/ivtv-driver.c @@ -351,6 +351,7 @@ static void ivtv_process_eeprom(struct ivtv *itv) case 23000 ... 23999: /* PVR500 */ case 25000 ... 25999: /* Low profile PVR150 */ case 26000 ... 26999: /* Regular PVR150 */ + case 30012 ... 30039: /* Low profile PVR150 */ itv->card = ivtv_get_card(IVTV_CARD_PVR_150); break; case 0: -- cgit v1.2.3 From f662d092575c7c6cb88b927c0315d373b2dcf526 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 17 May 2007 12:29:57 +0200 Subject: Fix v4l2-ctl: comment out top/left usage From: Hans Verkuil The patch that broke the ABI was reverted. Also revert the changes in v4l2-ctl that used that new functionality. Signed-off-by: Hans Verkuil --- v4l2-apps/util/v4l2-ctl.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/v4l2-apps/util/v4l2-ctl.cpp b/v4l2-apps/util/v4l2-ctl.cpp index 4493ab438..35d9f466b 100644 --- a/v4l2-apps/util/v4l2-ctl.cpp +++ b/v4l2-apps/util/v4l2-ctl.cpp @@ -686,11 +686,14 @@ static int printfmt(struct v4l2_format vfmt) printf("\tBytes per Line: %u\n", vfmt.fmt.pix.bytesperline); printf("\tSize Image : %u\n", vfmt.fmt.pix.sizeimage); printf("\tColorspace : %s\n", colorspace2s(vfmt.fmt.pix.colorspace).c_str()); +#if 0 + /* Comment out until ABI breakage is resolved */ if (vfmt.type == V4L2_BUF_TYPE_VIDEO_OUTPUT && (capabilities & V4L2_CAP_VIDEO_OUTPUT_POS)) { printf("\tLeft/Top : %d/%d\n", vfmt.fmt.pix.left, vfmt.fmt.pix.top); } +#endif if (vfmt.fmt.pix.priv) printf("\tCustom Info : %08x\n", vfmt.fmt.pix.priv); break; @@ -1155,6 +1158,8 @@ int main(int argc, char **argv) }; switch (parse_subopt(&subs, subopts, &value)) { +#if 0 + /* Comment out until ABI breakage is resolved */ case 0: vfmt_out.fmt.pix.top = strtol(value, 0L, 0); set_fmts_out |= FmtTop; @@ -1163,6 +1168,7 @@ int main(int argc, char **argv) vfmt_out.fmt.pix.left = strtol(value, 0L, 0); set_fmts_out |= FmtLeft; break; +#endif case 2: vfmt_out.fmt.pix.width = strtol(value, 0L, 0); set_fmts_out |= FmtWidth; @@ -1552,10 +1558,13 @@ int main(int argc, char **argv) if (ioctl(fd, VIDIOC_G_FMT, &in_vfmt) < 0) fprintf(stderr, "ioctl: VIDIOC_G_FMT failed\n"); else { +#if 0 + /* Comment out until ABI breakage is resolved */ if (set_fmts_out & FmtTop) in_vfmt.fmt.pix.top = vfmt_out.fmt.pix.top; if (set_fmts_out & FmtLeft) in_vfmt.fmt.pix.left = vfmt_out.fmt.pix.left; +#endif if (set_fmts_out & FmtWidth) in_vfmt.fmt.pix.width = vfmt_out.fmt.pix.width; if (set_fmts_out & FmtHeight) -- cgit v1.2.3 From a2caded8479fee8582e178cbd9785ebb44072e0f Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 17 May 2007 13:08:45 +0200 Subject: Fix audio stuttering for saa711x/ivtv when in radio mode. From: Hans Verkuil Signed-off-by: Jose Alberto Reguero Signed-off-by: Hans Verkuil --- linux/drivers/media/video/ivtv/ivtv-fileops.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/linux/drivers/media/video/ivtv/ivtv-fileops.c b/linux/drivers/media/video/ivtv/ivtv-fileops.c index 8976487a6..555d5e636 100644 --- a/linux/drivers/media/video/ivtv/ivtv-fileops.c +++ b/linux/drivers/media/video/ivtv/ivtv-fileops.c @@ -32,6 +32,8 @@ #include "ivtv-yuv.h" #include "ivtv-controls.h" #include "ivtv-ioctl.h" +#include "ivtv-cards.h" +#include /* This function tries to claim the stream for a specific file descriptor. If no one else is using this stream then the stream is claimed and @@ -786,6 +788,13 @@ int ivtv_v4l2_close(struct inode *inode, struct file *filp) ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std); /* Select correct audio input (i.e. TV tuner or Line in) */ ivtv_audio_set_io(itv); + if (itv->hw_flags & IVTV_HW_SAA711X) + { + struct v4l2_crystal_freq crystal_freq; + crystal_freq.freq = SAA7115_FREQ_32_11_MHZ; + crystal_freq.flags = 0; + ivtv_saa7115(itv, VIDIOC_INT_S_CRYSTAL_FREQ, &crystal_freq); + } /* Done! Unmute and continue. */ ivtv_unmute(itv); ivtv_release_stream(s); @@ -872,6 +881,13 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp) set_bit(IVTV_F_I_RADIO_USER, &itv->i_flags); /* Select the correct audio input (i.e. radio tuner) */ ivtv_audio_set_io(itv); + if (itv->hw_flags & IVTV_HW_SAA711X) + { + struct v4l2_crystal_freq crystal_freq; + crystal_freq.freq = SAA7115_FREQ_32_11_MHZ; + crystal_freq.flags = SAA7115_FREQ_FL_APLL; + ivtv_saa7115(itv, VIDIOC_INT_S_CRYSTAL_FREQ, &crystal_freq); + } /* Done! Unmute and continue. */ ivtv_unmute(itv); } -- cgit v1.2.3 From 959f6751c5ae7fef6940165071ef03a07ef9e731 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 18 May 2007 21:18:17 +0200 Subject: Models 30012-30039 are for a low profile PVR250, not PVR150. From: Hans Verkuil Signed-off-by: Hans Verkuil --- linux/drivers/media/video/ivtv/ivtv-driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/drivers/media/video/ivtv/ivtv-driver.c b/linux/drivers/media/video/ivtv/ivtv-driver.c index e0f6d4363..14dc4bca0 100644 --- a/linux/drivers/media/video/ivtv/ivtv-driver.c +++ b/linux/drivers/media/video/ivtv/ivtv-driver.c @@ -339,6 +339,7 @@ static void ivtv_process_eeprom(struct ivtv *itv) /* In a few cases the PCI subsystem IDs do not correctly identify the card. A better method is to check the model number from the eeprom instead. */ + case 30012 ... 30039: /* Low profile PVR250 */ case 32000 ... 32999: case 48000 ... 48099: /* 48??? range are PVR250s with a cx23415 */ case 48400 ... 48599: @@ -351,7 +352,6 @@ static void ivtv_process_eeprom(struct ivtv *itv) case 23000 ... 23999: /* PVR500 */ case 25000 ... 25999: /* Low profile PVR150 */ case 26000 ... 26999: /* Regular PVR150 */ - case 30012 ... 30039: /* Low profile PVR150 */ itv->card = ivtv_get_card(IVTV_CARD_PVR_150); break; case 0: -- cgit v1.2.3 From e65320dd8af749a0fe8242b59921b56d4eaf8d27 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 19 May 2007 19:07:16 +0200 Subject: Move big PIO accesses from the interrupt handler to a workhandler From: Hans Verkuil Sliced VBI transfers use PIO instead of DMA. This was done inside the interrupt handler, but since PIO accesses are very slow this meant that a lot of time was spent inside the interrupt handler. All PIO copies are now moved to a workqueue. This should fix various issues with missing time ticks and remote key hits. Signed-off-by: Hans Verkuil --- linux/drivers/media/video/ivtv/ivtv-driver.c | 1 + linux/drivers/media/video/ivtv/ivtv-driver.h | 16 ++- linux/drivers/media/video/ivtv/ivtv-irq.c | 204 ++++++++++++++++++--------- linux/drivers/media/video/ivtv/ivtv-queue.c | 31 ++-- linux/drivers/media/video/ivtv/ivtv-queue.h | 39 ++++- linux/drivers/media/video/ivtv/ivtv-vbi.c | 2 +- linux/drivers/media/video/ivtv/ivtv-vbi.h | 2 +- 7 files changed, 209 insertions(+), 86 deletions(-) diff --git a/linux/drivers/media/video/ivtv/ivtv-driver.c b/linux/drivers/media/video/ivtv/ivtv-driver.c index 14dc4bca0..b0c11d90e 100644 --- a/linux/drivers/media/video/ivtv/ivtv-driver.c +++ b/linux/drivers/media/video/ivtv/ivtv-driver.c @@ -657,6 +657,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv) itv->dma_timer.data = (unsigned long)itv; itv->cur_dma_stream = -1; + itv->cur_pio_stream = -1; itv->audio_stereo_mode = AUDIO_STEREO; itv->audio_bilingual_mode = AUDIO_MONO_LEFT; diff --git a/linux/drivers/media/video/ivtv/ivtv-driver.h b/linux/drivers/media/video/ivtv/ivtv-driver.h index 604448dd1..7b162e415 100644 --- a/linux/drivers/media/video/ivtv/ivtv-driver.h +++ b/linux/drivers/media/video/ivtv/ivtv-driver.h @@ -240,6 +240,7 @@ extern const u32 yuv_offset[4]; #define IVTV_IRQ_ENC_VBI_CAP (0x1 << 29) #define IVTV_IRQ_ENC_VIM_RST (0x1 << 28) #define IVTV_IRQ_ENC_DMA_COMPLETE (0x1 << 27) +#define IVTV_IRQ_ENC_PIO_COMPLETE (0x1 << 25) #define IVTV_IRQ_DEC_AUD_MODE_CHG (0x1 << 24) #define IVTV_IRQ_DEC_DATA_REQ (0x1 << 22) #define IVTV_IRQ_DEC_DMA_COMPLETE (0x1 << 20) @@ -250,7 +251,8 @@ extern const u32 yuv_offset[4]; #define IVTV_IRQ_DEC_VSYNC (0x1 << 10) /* IRQ Masks */ -#define IVTV_IRQ_MASK_INIT (IVTV_IRQ_DMA_ERR|IVTV_IRQ_ENC_DMA_COMPLETE|IVTV_IRQ_DMA_READ) +#define IVTV_IRQ_MASK_INIT (IVTV_IRQ_DMA_ERR|IVTV_IRQ_ENC_DMA_COMPLETE|\ + IVTV_IRQ_DMA_READ|IVTV_IRQ_ENC_PIO_COMPLETE) #define IVTV_IRQ_MASK_CAPTURE (IVTV_IRQ_ENC_START_CAP | IVTV_IRQ_ENC_EOS) #define IVTV_IRQ_MASK_DECODE (IVTV_IRQ_DEC_DATA_REQ|IVTV_IRQ_DEC_AUD_MODE_CHG) @@ -377,6 +379,9 @@ struct ivtv_mailbox_data { #define IVTV_F_S_STREAMOFF 7 /* signal end of stream EOS */ #define IVTV_F_S_APPL_IO 8 /* this stream is used read/written by an application */ +#define IVTV_F_S_PIO_PENDING 9 /* this stream has pending PIO */ +#define IVTV_F_S_PIO_HAS_VBI 1 /* the current PIO request also requests VBI data */ + /* per-ivtv, i_flags */ #define IVTV_F_I_DMA 0 /* DMA in progress */ #define IVTV_F_I_UDMA 1 /* UDMA in progress */ @@ -393,8 +398,11 @@ struct ivtv_mailbox_data { #define IVTV_F_I_DECODING_YUV 12 /* this stream is YUV frame decoding */ #define IVTV_F_I_ENC_PAUSED 13 /* the encoder is paused */ #define IVTV_F_I_VALID_DEC_TIMINGS 14 /* last_dec_timing is valid */ -#define IVTV_F_I_WORK_HANDLER_VBI 15 /* there is work to be done for VBI */ -#define IVTV_F_I_WORK_HANDLER_YUV 16 /* there is work to be done for YUV */ +#define IVTV_F_I_HAVE_WORK 15 /* Used in the interrupt handler: there is work to be done */ +#define IVTV_F_I_WORK_HANDLER_VBI 16 /* there is work to be done for VBI */ +#define IVTV_F_I_WORK_HANDLER_YUV 17 /* there is work to be done for YUV */ +#define IVTV_F_I_WORK_HANDLER_PIO 18 /* there is work to be done for PIO */ +#define IVTV_F_I_PIO 19 /* PIO in progress */ /* Event notifications */ #define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */ @@ -491,6 +499,7 @@ struct ivtv_stream { /* Base Dev SG Array for cx23415/6 */ struct ivtv_SG_element *SGarray; + struct ivtv_SG_element *PIOarray; dma_addr_t SG_handle; int SG_length; @@ -713,6 +722,7 @@ struct ivtv { atomic_t decoding; /* count number of active decoding streams */ u32 irq_rr_idx; /* Round-robin stream index */ int cur_dma_stream; /* index of stream doing DMA */ + int cur_pio_stream; /* index of stream doing PIO */ u32 dma_data_req_offset; u32 dma_data_req_size; int output_mode; /* NONE, MPG, YUV, UDMA YUV, passthrough */ diff --git a/linux/drivers/media/video/ivtv/ivtv-irq.c b/linux/drivers/media/video/ivtv/ivtv-irq.c index e87a4dc37..4825d1749 100644 --- a/linux/drivers/media/video/ivtv/ivtv-irq.c +++ b/linux/drivers/media/video/ivtv/ivtv-irq.c @@ -31,8 +31,6 @@ #define DMA_MAGIC_COOKIE 0x000001fe -#define SLICED_VBI_PIO 1 - static void ivtv_dma_dec_start(struct ivtv_stream *s); static const int ivtv_stream_map[] = { @@ -42,12 +40,40 @@ static const int ivtv_stream_map[] = { IVTV_ENC_STREAM_TYPE_VBI, }; -static inline int ivtv_use_pio(struct ivtv_stream *s) + +static void ivtv_pio_work_handler(struct ivtv *itv) { - struct ivtv *itv = s->itv; + struct ivtv_stream *s = &itv->streams[itv->cur_pio_stream]; + struct ivtv_buffer *buf; + struct list_head *p; + int i = 0; + + IVTV_DEBUG_DMA("ivtv_pio_work_handler\n"); + if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS || + s->v4l2dev == NULL || !ivtv_use_pio(s)) { + itv->cur_pio_stream = -1; + /* trigger PIO complete user interrupt */ + write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44); + return; + } + IVTV_DEBUG_DMA("Process PIO %s\n", s->name); + buf = list_entry(s->q_dma.list.next, struct ivtv_buffer, list); + list_for_each(p, &s->q_dma.list) { + struct ivtv_buffer *buf = list_entry(p, struct ivtv_buffer, list); + u32 size = s->PIOarray[i].size & 0x3ffff; - return s->dma == PCI_DMA_NONE || - (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set); + /* Copy the data from the card to the buffer */ + if (s->type == IVTV_DEC_STREAM_TYPE_VBI) { + memcpy_fromio(buf->buf, itv->dec_mem + s->PIOarray[i].src - IVTV_DECODER_OFFSET, size); + } + else { + memcpy_fromio(buf->buf, itv->enc_mem + s->PIOarray[i].src, size); + } + if (s->PIOarray[i].size & 0x80000000) + break; + i++; + } + write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44); } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) @@ -62,8 +88,11 @@ void ivtv_irq_work_handler(void *arg) DEFINE_WAIT(wait); + if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags)) + ivtv_pio_work_handler(itv); + if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags)) - vbi_work_handler(itv); + ivtv_vbi_work_handler(itv); if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags)) ivtv_yuv_work_handler(itv); @@ -179,8 +208,7 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA } s->buffers_stolen = rc; - /* got the buffers, now fill in SGarray (DMA) or copy the data from the card - to the buffers (PIO). */ + /* got the buffers, now fill in SGarray (DMA) */ buf = list_entry(s->q_predma.list.next, struct ivtv_buffer, list); memset(buf->buf, 0, 128); list_for_each(p, &s->q_predma.list) { @@ -188,21 +216,11 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA if (skip_bufs-- > 0) continue; - if (!ivtv_use_pio(s)) { - s->SGarray[idx].dst = cpu_to_le32(buf->dma_handle); - s->SGarray[idx].src = cpu_to_le32(offset); - s->SGarray[idx].size = cpu_to_le32(s->buf_size); - } + s->SGarray[idx].dst = cpu_to_le32(buf->dma_handle); + s->SGarray[idx].src = cpu_to_le32(offset); + s->SGarray[idx].size = cpu_to_le32(s->buf_size); buf->bytesused = (size < s->buf_size) ? size : s->buf_size; - /* If PIO, then copy the data from the card to the buffer */ - if (s->type == IVTV_DEC_STREAM_TYPE_VBI) { - memcpy_fromio(buf->buf, itv->dec_mem + offset - IVTV_DECODER_OFFSET, buf->bytesused); - } - else if (ivtv_use_pio(s)) { - memcpy_fromio(buf->buf, itv->enc_mem + offset, buf->bytesused); - } - s->q_predma.bytesused += buf->bytesused; size -= buf->bytesused; offset += s->buf_size; @@ -230,11 +248,6 @@ static void dma_post(struct ivtv_stream *s) u32 *u32buf; int x = 0; - if (ivtv_use_pio(s)) { - if (s->q_predma.bytesused) - ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused); - s->SG_length = 0; - } IVTV_DEBUG_DMA("%s %s completed (%x)\n", ivtv_use_pio(s) ? "PIO" : "DMA", s->name, s->dma_offset); list_for_each(p, &s->q_dma.list) { @@ -284,10 +297,14 @@ static void dma_post(struct ivtv_stream *s) if (buf) buf->bytesused += s->dma_last_offset; if (buf && s->type == IVTV_DEC_STREAM_TYPE_VBI) { - /* Parse and Groom VBI Data */ - s->q_dma.bytesused -= buf->bytesused; - ivtv_process_vbi_data(itv, buf, 0, s->type); - s->q_dma.bytesused += buf->bytesused; + list_for_each(p, &s->q_dma.list) { + buf = list_entry(p, struct ivtv_buffer, list); + + /* Parse and Groom VBI Data */ + s->q_dma.bytesused -= buf->bytesused; + ivtv_process_vbi_data(itv, buf, 0, s->type); + s->q_dma.bytesused += buf->bytesused; + } if (s->id == -1) { ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0); return; @@ -357,10 +374,14 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s) struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; int i; + IVTV_DEBUG_DMA("start %s for %s\n", ivtv_use_dma(s) ? "DMA" : "PIO", s->name); + if (s->q_predma.bytesused) ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused); - IVTV_DEBUG_DMA("start DMA for %s\n", s->name); - s->SGarray[s->SG_length - 1].size = cpu_to_le32(le32_to_cpu(s->SGarray[s->SG_length - 1].size) + 256); + + if (ivtv_use_dma(s)) + s->SGarray[s->SG_length - 1].size = + cpu_to_le32(le32_to_cpu(s->SGarray[s->SG_length - 1].size) + 256); /* If this is an MPEG stream, and VBI data is also pending, then append the VBI DMA to the MPEG DMA and transfer both sets of data at once. @@ -374,7 +395,8 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s) if (s->type == IVTV_ENC_STREAM_TYPE_MPG && s_vbi->SG_length && s->SG_length + s_vbi->SG_length <= s->buffers) { ivtv_queue_move(s_vbi, &s_vbi->q_predma, NULL, &s_vbi->q_dma, s_vbi->q_predma.bytesused); - s_vbi->SGarray[s_vbi->SG_length - 1].size = cpu_to_le32(le32_to_cpu(s_vbi->SGarray[s->SG_length - 1].size) + 256); + if (ivtv_use_dma(s_vbi)) + s_vbi->SGarray[s_vbi->SG_length - 1].size = cpu_to_le32(le32_to_cpu(s_vbi->SGarray[s->SG_length - 1].size) + 256); for (i = 0; i < s_vbi->SG_length; i++) { s->SGarray[s->SG_length++] = s_vbi->SGarray[i]; } @@ -387,14 +409,26 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s) /* Mark last buffer size for Interrupt flag */ s->SGarray[s->SG_length - 1].size |= cpu_to_le32(0x80000000); - /* Sync Hardware SG List of buffers */ - ivtv_stream_sync_for_device(s); - write_reg(s->SG_handle, IVTV_REG_ENCDMAADDR); - write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER); - set_bit(IVTV_F_I_DMA, &itv->i_flags); - itv->cur_dma_stream = s->type; - itv->dma_timer.expires = jiffies + HZ / 10; - add_timer(&itv->dma_timer); + if (ivtv_use_pio(s)) { + for (i = 0; i < s->SG_length; i++) { + s->PIOarray[i].src = le32_to_cpu(s->SGarray[i].src); + s->PIOarray[i].size = le32_to_cpu(s->SGarray[i].size); + } + set_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags); + set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags); + set_bit(IVTV_F_I_PIO, &itv->i_flags); + itv->cur_pio_stream = s->type; + } + else { + /* Sync Hardware SG List of buffers */ + ivtv_stream_sync_for_device(s); + write_reg(s->SG_handle, IVTV_REG_ENCDMAADDR); + write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER); + set_bit(IVTV_F_I_DMA, &itv->i_flags); + itv->cur_dma_stream = s->type; + itv->dma_timer.expires = jiffies + HZ / 10; + add_timer(&itv->dma_timer); + } } static void ivtv_dma_dec_start(struct ivtv_stream *s) @@ -495,6 +529,40 @@ static void ivtv_irq_enc_dma_complete(struct ivtv *itv) wake_up(&itv->dma_waitq); } +static void ivtv_irq_enc_pio_complete(struct ivtv *itv) +{ + struct ivtv_stream *s; + + if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS) { + itv->cur_pio_stream = -1; + return; + } + s = &itv->streams[itv->cur_pio_stream]; + IVTV_DEBUG_IRQ("ENC PIO COMPLETE %s\n", s->name); + s->SG_length = 0; + clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags); + clear_bit(IVTV_F_I_PIO, &itv->i_flags); + itv->cur_pio_stream = -1; + dma_post(s); + if (s->type == IVTV_ENC_STREAM_TYPE_MPG) + ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 0); + else if (s->type == IVTV_ENC_STREAM_TYPE_YUV) + ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 1); + else if (s->type == IVTV_ENC_STREAM_TYPE_PCM) + ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 2); + clear_bit(IVTV_F_I_PIO, &itv->i_flags); + if (test_and_clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags)) { + u32 tmp; + + s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; + tmp = s->dma_offset; + s->dma_offset = itv->vbi.dma_offset; + dma_post(s); + s->dma_offset = tmp; + } + wake_up(&itv->dma_waitq); +} + static void ivtv_irq_dma_err(struct ivtv *itv) { u32 data[CX2341X_MBOX_MAX_DATA]; @@ -538,13 +606,7 @@ static void ivtv_irq_enc_start_cap(struct ivtv *itv) clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags); s = &itv->streams[ivtv_stream_map[data[0]]]; if (!stream_enc_dma_append(s, data)) { - if (ivtv_use_pio(s)) { - dma_post(s); - ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, data[0]); - } - else { - set_bit(IVTV_F_S_DMA_PENDING, &s->s_flags); - } + set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags); } } @@ -557,15 +619,6 @@ static void ivtv_irq_enc_vbi_cap(struct ivtv *itv) IVTV_DEBUG_IRQ("ENC START VBI CAP\n"); s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; - if (ivtv_use_pio(s)) { - if (stream_enc_dma_append(s, data)) - return; - if (s->q_predma.bytesused) - ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused); - s->SG_length = 0; - dma_post(s); - return; - } /* If more than two VBI buffers are pending, then clear the old ones and start with this new one. This can happen during transition stages when MPEG capturing is @@ -588,11 +641,11 @@ static void ivtv_irq_enc_vbi_cap(struct ivtv *itv) if (!stream_enc_dma_append(s, data) && !test_bit(IVTV_F_S_STREAMING, &s_mpg->s_flags)) { set_bit(IVTV_F_I_ENC_VBI, &itv->i_flags); - set_bit(IVTV_F_S_DMA_PENDING, &s->s_flags); + set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags); } } -static void ivtv_irq_dev_vbi_reinsert(struct ivtv *itv) +static void ivtv_irq_dec_vbi_reinsert(struct ivtv *itv) { u32 data[CX2341X_MBOX_MAX_DATA]; struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_VBI]; @@ -600,7 +653,7 @@ static void ivtv_irq_dev_vbi_reinsert(struct ivtv *itv) IVTV_DEBUG_IRQ("DEC VBI REINSERT\n"); if (test_bit(IVTV_F_S_CLAIMED, &s->s_flags) && !stream_enc_dma_append(s, data)) { - dma_post(s); + set_bit(IVTV_F_S_PIO_PENDING, &s->s_flags); } } @@ -663,7 +716,6 @@ static void ivtv_irq_vsync(struct ivtv *itv) } if (frame != (itv->lastVsyncFrame & 1)) { struct ivtv_stream *s = ivtv_get_output_stream(itv); - int work = 0; itv->lastVsyncFrame += 1; if (frame == 0) { @@ -684,7 +736,7 @@ static void ivtv_irq_vsync(struct ivtv *itv) /* Send VBI to saa7127 */ if (frame) { set_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags); - work = 1; + set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags); } /* Check if we need to update the yuv registers */ @@ -697,11 +749,9 @@ static void ivtv_irq_vsync(struct ivtv *itv) itv->yuv_info.new_frame_info[last_dma_frame].update = 0; itv->yuv_info.yuv_forced_update = 0; set_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags); - work = 1; + set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags); } } - if (work) - queue_work(itv->irq_work_queues, &itv->irq_work_queue); } } @@ -765,6 +815,10 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id) ivtv_irq_enc_dma_complete(itv); } + if (combo & IVTV_IRQ_ENC_PIO_COMPLETE) { + ivtv_irq_enc_pio_complete(itv); + } + if (combo & IVTV_IRQ_DMA_ERR) { ivtv_irq_dma_err(itv); } @@ -778,7 +832,7 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id) } if (combo & IVTV_IRQ_DEC_VBI_RE_INSERT) { - ivtv_irq_dev_vbi_reinsert(itv); + ivtv_irq_dec_vbi_reinsert(itv); } if (combo & IVTV_IRQ_ENC_EOS) { @@ -823,6 +877,22 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id) } } + if ((combo & IVTV_IRQ_DMA) && !test_bit(IVTV_F_I_PIO, &itv->i_flags)) { + for (i = 0; i < IVTV_MAX_STREAMS; i++) { + int idx = (i + itv->irq_rr_idx++) % IVTV_MAX_STREAMS; + struct ivtv_stream *s = &itv->streams[idx]; + + if (!test_and_clear_bit(IVTV_F_S_PIO_PENDING, &s->s_flags)) + continue; + if (s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type < IVTV_DEC_STREAM_TYPE_MPG) + ivtv_dma_enc_start(s); + break; + } + } + + if (test_and_clear_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags)) + queue_work(itv->irq_work_queues, &itv->irq_work_queue); + spin_unlock(&itv->dma_reg_lock); /* If we've just handled a 'forced' vsync, it's safest to say it diff --git a/linux/drivers/media/video/ivtv/ivtv-queue.c b/linux/drivers/media/video/ivtv/ivtv-queue.c index ccfcef1ad..a04f9387f 100644 --- a/linux/drivers/media/video/ivtv/ivtv-queue.c +++ b/linux/drivers/media/video/ivtv/ivtv-queue.c @@ -195,14 +195,26 @@ int ivtv_stream_alloc(struct ivtv_stream *s) s->dma != PCI_DMA_NONE ? "DMA " : "", s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024); - /* Allocate DMA SG Arrays */ - if (s->dma != PCI_DMA_NONE) { - s->SGarray = (struct ivtv_SG_element *)kzalloc(SGsize, GFP_KERNEL); - if (s->SGarray == NULL) { - IVTV_ERR("Could not allocate SGarray for %s stream\n", s->name); + if (ivtv_might_use_pio(s)) { + s->PIOarray = (struct ivtv_SG_element *)kzalloc(SGsize, GFP_KERNEL); + if (s->PIOarray == NULL) { + IVTV_ERR("Could not allocate PIOarray for %s stream\n", s->name); return -ENOMEM; } - s->SG_length = 0; + } + + /* Allocate DMA SG Arrays */ + s->SGarray = (struct ivtv_SG_element *)kzalloc(SGsize, GFP_KERNEL); + if (s->SGarray == NULL) { + IVTV_ERR("Could not allocate SGarray for %s stream\n", s->name); + if (ivtv_might_use_pio(s)) { + kfree(s->PIOarray); + s->PIOarray = NULL; + } + return -ENOMEM; + } + s->SG_length = 0; + if (ivtv_might_use_dma(s)) { s->SG_handle = pci_map_single(itv->dev, s->SGarray, SGsize, s->dma); ivtv_stream_sync_for_cpu(s); } @@ -219,7 +231,7 @@ int ivtv_stream_alloc(struct ivtv_stream *s) break; } INIT_LIST_HEAD(&buf->list); - if (s->dma != PCI_DMA_NONE) { + if (ivtv_might_use_dma(s)) { buf->dma_handle = pci_map_single(s->itv->dev, buf->buf, s->buf_size + 256, s->dma); ivtv_buf_sync_for_cpu(s, buf); @@ -242,7 +254,7 @@ void ivtv_stream_free(struct ivtv_stream *s) /* empty q_free */ while ((buf = ivtv_dequeue(s, &s->q_free))) { - if (s->dma != PCI_DMA_NONE) + if (ivtv_might_use_dma(s)) pci_unmap_single(s->itv->dev, buf->dma_handle, s->buf_size + 256, s->dma); kfree(buf->buf); @@ -256,6 +268,9 @@ void ivtv_stream_free(struct ivtv_stream *s) sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE); s->SG_handle = IVTV_DMA_UNMAPPED; } + kfree(s->SGarray); + kfree(s->PIOarray); + s->PIOarray = NULL; s->SGarray = NULL; s->SG_length = 0; } diff --git a/linux/drivers/media/video/ivtv/ivtv-queue.h b/linux/drivers/media/video/ivtv/ivtv-queue.h index 903edd4b4..2ed8d5482 100644 --- a/linux/drivers/media/video/ivtv/ivtv-queue.h +++ b/linux/drivers/media/video/ivtv/ivtv-queue.h @@ -20,18 +20,43 @@ */ #define IVTV_DMA_UNMAPPED ((u32) -1) +#define SLICED_VBI_PIO 1 /* ivtv_buffer utility functions */ + +static inline int ivtv_might_use_pio(struct ivtv_stream *s) +{ + return s->dma == PCI_DMA_NONE || (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI); +} + +static inline int ivtv_use_pio(struct ivtv_stream *s) +{ + struct ivtv *itv = s->itv; + + return s->dma == PCI_DMA_NONE || + (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set); +} + +static inline int ivtv_might_use_dma(struct ivtv_stream *s) +{ + return s->dma != PCI_DMA_NONE; +} + +static inline int ivtv_use_dma(struct ivtv_stream *s) +{ + return !ivtv_use_pio(s); +} + static inline void ivtv_buf_sync_for_cpu(struct ivtv_stream *s, struct ivtv_buffer *buf) { - if (s->dma != PCI_DMA_NONE) + if (ivtv_use_dma(s)) pci_dma_sync_single_for_cpu(s->itv->dev, buf->dma_handle, s->buf_size + 256, s->dma); } static inline void ivtv_buf_sync_for_device(struct ivtv_stream *s, struct ivtv_buffer *buf) { - if (s->dma != PCI_DMA_NONE) + if (ivtv_use_dma(s)) pci_dma_sync_single_for_device(s->itv->dev, buf->dma_handle, s->buf_size + 256, s->dma); } @@ -53,12 +78,14 @@ void ivtv_stream_free(struct ivtv_stream *s); static inline void ivtv_stream_sync_for_cpu(struct ivtv_stream *s) { - pci_dma_sync_single_for_cpu(s->itv->dev, s->SG_handle, - sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE); + if (ivtv_use_dma(s)) + pci_dma_sync_single_for_cpu(s->itv->dev, s->SG_handle, + sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE); } static inline void ivtv_stream_sync_for_device(struct ivtv_stream *s) { - pci_dma_sync_single_for_device(s->itv->dev, s->SG_handle, - sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE); + if (ivtv_use_dma(s)) + pci_dma_sync_single_for_device(s->itv->dev, s->SG_handle, + sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE); } diff --git a/linux/drivers/media/video/ivtv/ivtv-vbi.c b/linux/drivers/media/video/ivtv/ivtv-vbi.c index 5efa5a867..3ba46e07e 100644 --- a/linux/drivers/media/video/ivtv/ivtv-vbi.c +++ b/linux/drivers/media/video/ivtv/ivtv-vbi.c @@ -450,7 +450,7 @@ void ivtv_disable_vbi(struct ivtv *itv) } -void vbi_work_handler(struct ivtv *itv) +void ivtv_vbi_work_handler(struct ivtv *itv) { struct v4l2_sliced_vbi_data data; diff --git a/linux/drivers/media/video/ivtv/ivtv-vbi.h b/linux/drivers/media/video/ivtv/ivtv-vbi.h index cdaea697b..ec211b497 100644 --- a/linux/drivers/media/video/ivtv/ivtv-vbi.h +++ b/linux/drivers/media/video/ivtv/ivtv-vbi.h @@ -23,4 +23,4 @@ void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf, int ivtv_used_line(struct ivtv *itv, int line, int field); void ivtv_disable_vbi(struct ivtv *itv); void ivtv_set_vbi(unsigned long arg); -void vbi_work_handler(struct ivtv *itv); +void ivtv_vbi_work_handler(struct ivtv *itv); -- cgit v1.2.3 From 29993ba41c50e8096ffd25fe704990479248d061 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 19 May 2007 19:50:35 +0200 Subject: Use v4l2_pix_out_fmt instead of v4l2_pix_fmt for video output format From: Hans Verkuil Adding top/left fields to v4l2_pix_fmt broke the ABI. To fix this a new v4l2_pix_out_fmt struct was introduced to specify the video output format. This new struct *does* have the additional top/left fields. The V4L2_CAP_VIDEO_OUTPUT_POS capability that was introduced is no longer needed and is removed. Signed-off-by: Hans Verkuil --- linux/drivers/media/video/ivtv/ivtv-cards.h | 2 +- linux/drivers/media/video/ivtv/ivtv-ioctl.c | 81 ++++++++++------------------- linux/drivers/media/video/zoran_driver.c | 6 ++- linux/include/linux/videodev2.h | 21 +++++++- v4l2-apps/util/v4l2-ctl.cpp | 45 +++++++--------- v4l2-apps/util/v4l2-dbg.cpp | 2 - 6 files changed, 72 insertions(+), 85 deletions(-) diff --git a/linux/drivers/media/video/ivtv/ivtv-cards.h b/linux/drivers/media/video/ivtv/ivtv-cards.h index 15012f88b..91e9e90c1 100644 --- a/linux/drivers/media/video/ivtv/ivtv-cards.h +++ b/linux/drivers/media/video/ivtv/ivtv-cards.h @@ -86,7 +86,7 @@ V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE | \ V4L2_CAP_SLICED_VBI_CAPTURE) #define IVTV_CAP_DECODER (V4L2_CAP_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT | \ - V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY | V4L2_CAP_VIDEO_OUTPUT_POS) + V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY) struct ivtv_card_video_input { u8 video_type; /* video input type */ diff --git a/linux/drivers/media/video/ivtv/ivtv-ioctl.c b/linux/drivers/media/video/ivtv/ivtv-ioctl.c index 5b799f016..15c2c9f5c 100644 --- a/linux/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/linux/drivers/media/video/ivtv/ivtv-ioctl.c @@ -362,56 +362,46 @@ static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fm case V4L2_BUF_TYPE_VIDEO_OUTPUT: if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) return -EINVAL; -#if 0 - /* Temporarily removed until a better solution is in place that does not - break the ABI */ - fmt->fmt.pix.left = itv->main_rect.left; - fmt->fmt.pix.top = itv->main_rect.top; -#endif - fmt->fmt.pix.width = itv->main_rect.width; - fmt->fmt.pix.height = itv->main_rect.height; - fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; - fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; + fmt->fmt.pix_out.left = itv->main_rect.left; + fmt->fmt.pix_out.top = itv->main_rect.top; + fmt->fmt.pix_out.width = itv->main_rect.width; + fmt->fmt.pix_out.height = itv->main_rect.height; + fmt->fmt.pix_out.colorspace = V4L2_COLORSPACE_SMPTE170M; + fmt->fmt.pix_out.field = V4L2_FIELD_INTERLACED; if (itv->output_mode == OUT_UDMA_YUV) { switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) { case IVTV_YUV_MODE_INTERLACED: - fmt->fmt.pix.field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ? + fmt->fmt.pix_out.field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ? V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB; break; case IVTV_YUV_MODE_PROGRESSIVE: - fmt->fmt.pix.field = V4L2_FIELD_NONE; + fmt->fmt.pix_out.field = V4L2_FIELD_NONE; break; default: - fmt->fmt.pix.field = V4L2_FIELD_ANY; + fmt->fmt.pix_out.field = V4L2_FIELD_ANY; break; } - fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12; + fmt->fmt.pix_out.pixelformat = V4L2_PIX_FMT_HM12; /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ - fmt->fmt.pix.sizeimage = + fmt->fmt.pix_out.sizeimage = fmt->fmt.pix.height * fmt->fmt.pix.width + fmt->fmt.pix.height * (fmt->fmt.pix.width / 2); } else if (itv->output_mode == OUT_YUV || streamtype == IVTV_ENC_STREAM_TYPE_YUV || streamtype == IVTV_DEC_STREAM_TYPE_YUV) { - fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12; + fmt->fmt.pix_out.pixelformat = V4L2_PIX_FMT_HM12; /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ - fmt->fmt.pix.sizeimage = - fmt->fmt.pix.height * fmt->fmt.pix.width + - fmt->fmt.pix.height * (fmt->fmt.pix.width / 2); + fmt->fmt.pix_out.sizeimage = + fmt->fmt.pix_out.height * fmt->fmt.pix_out.width + + fmt->fmt.pix_out.height * (fmt->fmt.pix_out.width / 2); } else { - fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - fmt->fmt.pix.sizeimage = 128 * 1024; + fmt->fmt.pix_out.pixelformat = V4L2_PIX_FMT_MPEG; + fmt->fmt.pix_out.sizeimage = 128 * 1024; } break; case V4L2_BUF_TYPE_VIDEO_CAPTURE: -#if 0 - /* Temporarily removed until a better solution is in place that does not - break the ABI */ - fmt->fmt.pix.left = 0; - fmt->fmt.pix.top = 0; -#endif fmt->fmt.pix.width = itv->params.width; fmt->fmt.pix.height = itv->params.height; fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; @@ -505,33 +495,22 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype, if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) return -EINVAL; - field = fmt->fmt.pix.field; -#if 0 - /* Temporarily removed until a better solution is in place that does not - break the ABI */ - r.top = fmt->fmt.pix.top; - r.left = fmt->fmt.pix.left; -#else - r.top = 0; - r.left = 0; -#endif - r.width = fmt->fmt.pix.width; - r.height = fmt->fmt.pix.height; + field = fmt->fmt.pix_out.field; + r.top = fmt->fmt.pix_out.top; + r.left = fmt->fmt.pix_out.left; + r.width = fmt->fmt.pix_out.width; + r.height = fmt->fmt.pix_out.height; ivtv_get_fmt(itv, streamtype, fmt); if (itv->output_mode != OUT_UDMA_YUV) { /* TODO: would setting the rect also be valid for this mode? */ -#if 0 - /* Temporarily removed until a better solution is in place that does not - break the ABI */ - fmt->fmt.pix.top = r.top; - fmt->fmt.pix.left = r.left; -#endif - fmt->fmt.pix.width = r.width; - fmt->fmt.pix.height = r.height; + fmt->fmt.pix_out.top = r.top; + fmt->fmt.pix_out.left = r.left; + fmt->fmt.pix_out.width = r.width; + fmt->fmt.pix_out.height = r.height; } if (itv->output_mode == OUT_UDMA_YUV) { /* TODO: add checks for validity */ - fmt->fmt.pix.field = field; + fmt->fmt.pix_out.field = field; } if (set_fmt) { if (itv->output_mode == OUT_UDMA_YUV) { @@ -1172,12 +1151,6 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void fb->fmt.pixelformat = itv->osd_pixelformat; fb->fmt.width = itv->osd_rect.width; fb->fmt.height = itv->osd_rect.height; -#if 0 - /* Temporarily removed until a better solution is in place that does not - break the ABI */ - fb->fmt.left = itv->osd_rect.left; - fb->fmt.top = itv->osd_rect.top; -#endif fb->base = (void *)itv->osd_video_pbase; if (itv->osd_global_alpha_state) fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; diff --git a/linux/drivers/media/video/zoran_driver.c b/linux/drivers/media/video/zoran_driver.c index de85abc45..38c1c5978 100644 --- a/linux/drivers/media/video/zoran_driver.c +++ b/linux/drivers/media/video/zoran_driver.c @@ -2894,8 +2894,12 @@ zoran_do_ioctl (struct inode *inode, return res; break; - case V4L2_BUF_TYPE_VIDEO_CAPTURE: case V4L2_BUF_TYPE_VIDEO_OUTPUT: + /* Clear v4l2_pix_out_format fields, the position is always 0. */ + fmt->fmt.pix_out.top = 0; + fmt->fmt.pix_out.left = 0; + /* fall through */ + case V4L2_BUF_TYPE_VIDEO_CAPTURE: printformat = __cpu_to_le32(fmt->fmt.pix.pixelformat); diff --git a/linux/include/linux/videodev2.h b/linux/include/linux/videodev2.h index 8e46a2029..3d92c6b69 100644 --- a/linux/include/linux/videodev2.h +++ b/linux/include/linux/videodev2.h @@ -243,8 +243,7 @@ struct v4l2_capability #define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */ #define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */ #define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */ -#define V4L2_CAP_VIDEO_OUTPUT_POS 0x00000200 /* Video output can have x,y coords */ -#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000400 /* Can do video output overlay */ +#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000200 /* Can do video output overlay */ #define V4L2_CAP_TUNER 0x00010000 /* has a tuner */ #define V4L2_CAP_AUDIO 0x00020000 /* has audio support */ @@ -1274,6 +1273,23 @@ struct v4l2_encoder_cmd { * Data services API by Michael Schimek */ +/* Video output format */ +/* The first part of this structure is identical to the v4l2_pix_format + structure, the fields after 'priv' are specific to the video output format. */ +struct v4l2_pix_out_format +{ + __u32 width; + __u32 height; + __u32 pixelformat; + enum v4l2_field field; + __u32 bytesperline; /* for padding, zero if unused */ + __u32 sizeimage; + enum v4l2_colorspace colorspace; + __u32 priv; /* private data, depends on pixelformat */ + __u32 top; + __u32 left; +}; + /* Raw VBI */ struct v4l2_vbi_format { @@ -1356,6 +1372,7 @@ struct v4l2_format union { struct v4l2_pix_format pix; // V4L2_BUF_TYPE_VIDEO_CAPTURE + struct v4l2_pix_out_format pix_out; // V4L2_BUF_TYPE_VIDEO_OUTPUT struct v4l2_window win; // V4L2_BUF_TYPE_VIDEO_OVERLAY struct v4l2_vbi_format vbi; // V4L2_BUF_TYPE_VBI_CAPTURE struct v4l2_sliced_vbi_format sliced; // V4L2_BUF_TYPE_SLICED_VBI_CAPTURE diff --git a/v4l2-apps/util/v4l2-ctl.cpp b/v4l2-apps/util/v4l2-ctl.cpp index 35d9f466b..0ce63bb1a 100644 --- a/v4l2-apps/util/v4l2-ctl.cpp +++ b/v4l2-apps/util/v4l2-ctl.cpp @@ -678,7 +678,6 @@ static int printfmt(struct v4l2_format vfmt) switch (vfmt.type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: - case V4L2_BUF_TYPE_VIDEO_OUTPUT: printf("\tType : %s\n", buftype2s(vfmt.type).c_str()); printf("\tWidth/Height : %u/%u\n", vfmt.fmt.pix.width, vfmt.fmt.pix.height); printf("\tPixel Format : %s\n", fcc2s(vfmt.fmt.pix.pixelformat).c_str()); @@ -686,17 +685,21 @@ static int printfmt(struct v4l2_format vfmt) printf("\tBytes per Line: %u\n", vfmt.fmt.pix.bytesperline); printf("\tSize Image : %u\n", vfmt.fmt.pix.sizeimage); printf("\tColorspace : %s\n", colorspace2s(vfmt.fmt.pix.colorspace).c_str()); -#if 0 - /* Comment out until ABI breakage is resolved */ - if (vfmt.type == V4L2_BUF_TYPE_VIDEO_OUTPUT && - (capabilities & V4L2_CAP_VIDEO_OUTPUT_POS)) { - printf("\tLeft/Top : %d/%d\n", - vfmt.fmt.pix.left, vfmt.fmt.pix.top); - } -#endif if (vfmt.fmt.pix.priv) printf("\tCustom Info : %08x\n", vfmt.fmt.pix.priv); break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + printf("\tType : %s\n", buftype2s(vfmt.type).c_str()); + printf("\tWidth/Height : %u/%u\n", vfmt.fmt.pix_out.width, vfmt.fmt.pix_out.height); + printf("\tPixel Format : %s\n", fcc2s(vfmt.fmt.pix_out.pixelformat).c_str()); + printf("\tField : %s\n", field2s(vfmt.fmt.pix_out.field).c_str()); + printf("\tBytes per Line: %u\n", vfmt.fmt.pix_out.bytesperline); + printf("\tSize Image : %u\n", vfmt.fmt.pix_out.sizeimage); + printf("\tColorspace : %s\n", colorspace2s(vfmt.fmt.pix_out.colorspace).c_str()); + printf("\tLeft/Top : %d/%d\n", vfmt.fmt.pix_out.left, vfmt.fmt.pix_out.top); + if (vfmt.fmt.pix_out.priv) + printf("\tCustom Info : %08x\n", vfmt.fmt.pix_out.priv); + break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: case V4L2_BUF_TYPE_VIDEO_OVERLAY: printf("\tType : %s\n", buftype2s(vfmt.type).c_str()); @@ -860,8 +863,6 @@ static std::string cap2s(unsigned cap) s += "\t\tSliced VBI Output\n"; if (cap & V4L2_CAP_RDS_CAPTURE) s += "\t\tRDS Capture\n"; - if (cap & V4L2_CAP_VIDEO_OUTPUT_POS) - s += "\t\tVideo Output Position\n"; if (cap & V4L2_CAP_TUNER) s += "\t\tTuner\n"; if (cap & V4L2_CAP_AUDIO) @@ -1158,23 +1159,20 @@ int main(int argc, char **argv) }; switch (parse_subopt(&subs, subopts, &value)) { -#if 0 - /* Comment out until ABI breakage is resolved */ case 0: - vfmt_out.fmt.pix.top = strtol(value, 0L, 0); + vfmt_out.fmt.pix_out.top = strtol(value, 0L, 0); set_fmts_out |= FmtTop; break; case 1: - vfmt_out.fmt.pix.left = strtol(value, 0L, 0); + vfmt_out.fmt.pix_out.left = strtol(value, 0L, 0); set_fmts_out |= FmtLeft; break; -#endif case 2: - vfmt_out.fmt.pix.width = strtol(value, 0L, 0); + vfmt_out.fmt.pix_out.width = strtol(value, 0L, 0); set_fmts_out |= FmtWidth; break; case 3: - vfmt_out.fmt.pix.height = strtol(value, 0L, 0); + vfmt_out.fmt.pix_out.height = strtol(value, 0L, 0); set_fmts_out |= FmtHeight; break; } @@ -1558,17 +1556,14 @@ int main(int argc, char **argv) if (ioctl(fd, VIDIOC_G_FMT, &in_vfmt) < 0) fprintf(stderr, "ioctl: VIDIOC_G_FMT failed\n"); else { -#if 0 - /* Comment out until ABI breakage is resolved */ if (set_fmts_out & FmtTop) - in_vfmt.fmt.pix.top = vfmt_out.fmt.pix.top; + in_vfmt.fmt.pix_out.top = vfmt_out.fmt.pix_out.top; if (set_fmts_out & FmtLeft) - in_vfmt.fmt.pix.left = vfmt_out.fmt.pix.left; -#endif + in_vfmt.fmt.pix_out.left = vfmt_out.fmt.pix_out.left; if (set_fmts_out & FmtWidth) - in_vfmt.fmt.pix.width = vfmt_out.fmt.pix.width; + in_vfmt.fmt.pix_out.width = vfmt_out.fmt.pix_out.width; if (set_fmts_out & FmtHeight) - in_vfmt.fmt.pix.height = vfmt_out.fmt.pix.height; + in_vfmt.fmt.pix_out.height = vfmt_out.fmt.pix_out.height; if (ioctl(fd, VIDIOC_S_FMT, &in_vfmt) < 0) fprintf(stderr, "ioctl: VIDIOC_S_FMT failed\n"); } diff --git a/v4l2-apps/util/v4l2-dbg.cpp b/v4l2-apps/util/v4l2-dbg.cpp index 6f373281e..10c9a8927 100644 --- a/v4l2-apps/util/v4l2-dbg.cpp +++ b/v4l2-apps/util/v4l2-dbg.cpp @@ -160,8 +160,6 @@ static std::string cap2s(unsigned cap) s += "\t\tSliced VBI Output\n"; if (cap & V4L2_CAP_RDS_CAPTURE) s += "\t\tRDS Capture\n"; - if (cap & V4L2_CAP_VIDEO_OUTPUT_POS) - s += "\t\tVideo Output Position\n"; if (cap & V4L2_CAP_TUNER) s += "\t\tTuner\n"; if (cap & V4L2_CAP_AUDIO) -- cgit v1.2.3 From 2454fcc21cbbd3c59ae9205c2d99b7849a5c5bed Mon Sep 17 00:00:00 2001 From: "royale@royale" Date: Sun, 20 May 2007 14:12:10 +0200 Subject: zr364xx: fix return values From: Akinobu Mita This patch fixes several return value related problems in zr364xx. - return -ENOMEM instead of -ENODEV on out of memory - zr364xx checks video_register_device() error only when its return value is -1. But video_register_device() doesn't always return -1 on error. - If usb_register() returns error, module_init() wrongly returns 1: retval = usb_register(&zr364xx_driver) < 0; ... return retval; And it allows the module to be loaded. Because sys_init_module() doesn't see positive return value as error. Signed-off-by: Akinobu Mita Signed-off-by: Antoine Jacquet --- linux/drivers/media/video/zr364xx.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/linux/drivers/media/video/zr364xx.c b/linux/drivers/media/video/zr364xx.c index 88b1fec85..b72d153c5 100644 --- a/linux/drivers/media/video/zr364xx.c +++ b/linux/drivers/media/video/zr364xx.c @@ -797,6 +797,7 @@ static int zr364xx_probe(struct usb_interface *intf, { struct usb_device *udev = interface_to_usbdev(intf); struct zr364xx_camera *cam = NULL; + int err; DBG("probing..."); @@ -804,12 +805,11 @@ static int zr364xx_probe(struct usb_interface *intf, info("model %04x:%04x detected", udev->descriptor.idVendor, udev->descriptor.idProduct); - if ((cam = - kmalloc(sizeof(struct zr364xx_camera), GFP_KERNEL)) == NULL) { + cam = kzalloc(sizeof(struct zr364xx_camera), GFP_KERNEL); + if (cam == NULL) { info("cam: out of memory !"); - return -ENODEV; + return -ENOMEM; } - memset(cam, 0x00, sizeof(struct zr364xx_camera)); /* save the init method used by this camera */ cam->method = id->driver_info; @@ -817,7 +817,7 @@ static int zr364xx_probe(struct usb_interface *intf, if (cam->vdev == NULL) { info("cam->vdev: out of memory !"); kfree(cam); - return -ENODEV; + return -ENOMEM; } memcpy(cam->vdev, &zr364xx_template, sizeof(zr364xx_template)); video_set_drvdata(cam->vdev, cam); @@ -863,12 +863,13 @@ static int zr364xx_probe(struct usb_interface *intf, cam->brightness = 64; mutex_init(&cam->lock); - if (video_register_device(cam->vdev, VFL_TYPE_GRABBER, -1) == -1) { + err = video_register_device(cam->vdev, VFL_TYPE_GRABBER, -1); + if (err) { info("video_register_device failed"); video_device_release(cam->vdev); kfree(cam->buffer); kfree(cam); - return -ENODEV; + return err; } usb_set_intfdata(intf, cam); @@ -910,7 +911,7 @@ static struct usb_driver zr364xx_driver = { static int __init zr364xx_init(void) { int retval; - retval = usb_register(&zr364xx_driver) < 0; + retval = usb_register(&zr364xx_driver); if (retval) info("usb_register failed!"); else -- cgit v1.2.3 From c5fbb8e80c9235232c11a933d7f0aef6b5734258 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 21 May 2007 12:44:02 +0200 Subject: Backed out changeset c7cb1aaec112a3ee7d6483b54d03d6a093754f10 --- linux/drivers/media/video/ivtv/ivtv-cards.h | 2 +- linux/drivers/media/video/ivtv/ivtv-ioctl.c | 81 +++++++++++++++++++---------- linux/drivers/media/video/zoran_driver.c | 6 +-- linux/include/linux/videodev2.h | 21 +------- v4l2-apps/util/v4l2-ctl.cpp | 45 +++++++++------- v4l2-apps/util/v4l2-dbg.cpp | 2 + 6 files changed, 85 insertions(+), 72 deletions(-) diff --git a/linux/drivers/media/video/ivtv/ivtv-cards.h b/linux/drivers/media/video/ivtv/ivtv-cards.h index 91e9e90c1..15012f88b 100644 --- a/linux/drivers/media/video/ivtv/ivtv-cards.h +++ b/linux/drivers/media/video/ivtv/ivtv-cards.h @@ -86,7 +86,7 @@ V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE | \ V4L2_CAP_SLICED_VBI_CAPTURE) #define IVTV_CAP_DECODER (V4L2_CAP_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT | \ - V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY) + V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY | V4L2_CAP_VIDEO_OUTPUT_POS) struct ivtv_card_video_input { u8 video_type; /* video input type */ diff --git a/linux/drivers/media/video/ivtv/ivtv-ioctl.c b/linux/drivers/media/video/ivtv/ivtv-ioctl.c index 15c2c9f5c..5b799f016 100644 --- a/linux/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/linux/drivers/media/video/ivtv/ivtv-ioctl.c @@ -362,46 +362,56 @@ static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fm case V4L2_BUF_TYPE_VIDEO_OUTPUT: if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) return -EINVAL; - fmt->fmt.pix_out.left = itv->main_rect.left; - fmt->fmt.pix_out.top = itv->main_rect.top; - fmt->fmt.pix_out.width = itv->main_rect.width; - fmt->fmt.pix_out.height = itv->main_rect.height; - fmt->fmt.pix_out.colorspace = V4L2_COLORSPACE_SMPTE170M; - fmt->fmt.pix_out.field = V4L2_FIELD_INTERLACED; +#if 0 + /* Temporarily removed until a better solution is in place that does not + break the ABI */ + fmt->fmt.pix.left = itv->main_rect.left; + fmt->fmt.pix.top = itv->main_rect.top; +#endif + fmt->fmt.pix.width = itv->main_rect.width; + fmt->fmt.pix.height = itv->main_rect.height; + fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; + fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; if (itv->output_mode == OUT_UDMA_YUV) { switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) { case IVTV_YUV_MODE_INTERLACED: - fmt->fmt.pix_out.field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ? + fmt->fmt.pix.field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ? V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB; break; case IVTV_YUV_MODE_PROGRESSIVE: - fmt->fmt.pix_out.field = V4L2_FIELD_NONE; + fmt->fmt.pix.field = V4L2_FIELD_NONE; break; default: - fmt->fmt.pix_out.field = V4L2_FIELD_ANY; + fmt->fmt.pix.field = V4L2_FIELD_ANY; break; } - fmt->fmt.pix_out.pixelformat = V4L2_PIX_FMT_HM12; + fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12; /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ - fmt->fmt.pix_out.sizeimage = + fmt->fmt.pix.sizeimage = fmt->fmt.pix.height * fmt->fmt.pix.width + fmt->fmt.pix.height * (fmt->fmt.pix.width / 2); } else if (itv->output_mode == OUT_YUV || streamtype == IVTV_ENC_STREAM_TYPE_YUV || streamtype == IVTV_DEC_STREAM_TYPE_YUV) { - fmt->fmt.pix_out.pixelformat = V4L2_PIX_FMT_HM12; + fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12; /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ - fmt->fmt.pix_out.sizeimage = - fmt->fmt.pix_out.height * fmt->fmt.pix_out.width + - fmt->fmt.pix_out.height * (fmt->fmt.pix_out.width / 2); + fmt->fmt.pix.sizeimage = + fmt->fmt.pix.height * fmt->fmt.pix.width + + fmt->fmt.pix.height * (fmt->fmt.pix.width / 2); } else { - fmt->fmt.pix_out.pixelformat = V4L2_PIX_FMT_MPEG; - fmt->fmt.pix_out.sizeimage = 128 * 1024; + fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; + fmt->fmt.pix.sizeimage = 128 * 1024; } break; case V4L2_BUF_TYPE_VIDEO_CAPTURE: +#if 0 + /* Temporarily removed until a better solution is in place that does not + break the ABI */ + fmt->fmt.pix.left = 0; + fmt->fmt.pix.top = 0; +#endif fmt->fmt.pix.width = itv->params.width; fmt->fmt.pix.height = itv->params.height; fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; @@ -495,22 +505,33 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype, if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) return -EINVAL; - field = fmt->fmt.pix_out.field; - r.top = fmt->fmt.pix_out.top; - r.left = fmt->fmt.pix_out.left; - r.width = fmt->fmt.pix_out.width; - r.height = fmt->fmt.pix_out.height; + field = fmt->fmt.pix.field; +#if 0 + /* Temporarily removed until a better solution is in place that does not + break the ABI */ + r.top = fmt->fmt.pix.top; + r.left = fmt->fmt.pix.left; +#else + r.top = 0; + r.left = 0; +#endif + r.width = fmt->fmt.pix.width; + r.height = fmt->fmt.pix.height; ivtv_get_fmt(itv, streamtype, fmt); if (itv->output_mode != OUT_UDMA_YUV) { /* TODO: would setting the rect also be valid for this mode? */ - fmt->fmt.pix_out.top = r.top; - fmt->fmt.pix_out.left = r.left; - fmt->fmt.pix_out.width = r.width; - fmt->fmt.pix_out.height = r.height; +#if 0 + /* Temporarily removed until a better solution is in place that does not + break the ABI */ + fmt->fmt.pix.top = r.top; + fmt->fmt.pix.left = r.left; +#endif + fmt->fmt.pix.width = r.width; + fmt->fmt.pix.height = r.height; } if (itv->output_mode == OUT_UDMA_YUV) { /* TODO: add checks for validity */ - fmt->fmt.pix_out.field = field; + fmt->fmt.pix.field = field; } if (set_fmt) { if (itv->output_mode == OUT_UDMA_YUV) { @@ -1151,6 +1172,12 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void fb->fmt.pixelformat = itv->osd_pixelformat; fb->fmt.width = itv->osd_rect.width; fb->fmt.height = itv->osd_rect.height; +#if 0 + /* Temporarily removed until a better solution is in place that does not + break the ABI */ + fb->fmt.left = itv->osd_rect.left; + fb->fmt.top = itv->osd_rect.top; +#endif fb->base = (void *)itv->osd_video_pbase; if (itv->osd_global_alpha_state) fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; diff --git a/linux/drivers/media/video/zoran_driver.c b/linux/drivers/media/video/zoran_driver.c index 38c1c5978..de85abc45 100644 --- a/linux/drivers/media/video/zoran_driver.c +++ b/linux/drivers/media/video/zoran_driver.c @@ -2894,12 +2894,8 @@ zoran_do_ioctl (struct inode *inode, return res; break; - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - /* Clear v4l2_pix_out_format fields, the position is always 0. */ - fmt->fmt.pix_out.top = 0; - fmt->fmt.pix_out.left = 0; - /* fall through */ case V4L2_BUF_TYPE_VIDEO_CAPTURE: + case V4L2_BUF_TYPE_VIDEO_OUTPUT: printformat = __cpu_to_le32(fmt->fmt.pix.pixelformat); diff --git a/linux/include/linux/videodev2.h b/linux/include/linux/videodev2.h index 3d92c6b69..8e46a2029 100644 --- a/linux/include/linux/videodev2.h +++ b/linux/include/linux/videodev2.h @@ -243,7 +243,8 @@ struct v4l2_capability #define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */ #define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */ #define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */ -#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000200 /* Can do video output overlay */ +#define V4L2_CAP_VIDEO_OUTPUT_POS 0x00000200 /* Video output can have x,y coords */ +#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000400 /* Can do video output overlay */ #define V4L2_CAP_TUNER 0x00010000 /* has a tuner */ #define V4L2_CAP_AUDIO 0x00020000 /* has audio support */ @@ -1273,23 +1274,6 @@ struct v4l2_encoder_cmd { * Data services API by Michael Schimek */ -/* Video output format */ -/* The first part of this structure is identical to the v4l2_pix_format - structure, the fields after 'priv' are specific to the video output format. */ -struct v4l2_pix_out_format -{ - __u32 width; - __u32 height; - __u32 pixelformat; - enum v4l2_field field; - __u32 bytesperline; /* for padding, zero if unused */ - __u32 sizeimage; - enum v4l2_colorspace colorspace; - __u32 priv; /* private data, depends on pixelformat */ - __u32 top; - __u32 left; -}; - /* Raw VBI */ struct v4l2_vbi_format { @@ -1372,7 +1356,6 @@ struct v4l2_format union { struct v4l2_pix_format pix; // V4L2_BUF_TYPE_VIDEO_CAPTURE - struct v4l2_pix_out_format pix_out; // V4L2_BUF_TYPE_VIDEO_OUTPUT struct v4l2_window win; // V4L2_BUF_TYPE_VIDEO_OVERLAY struct v4l2_vbi_format vbi; // V4L2_BUF_TYPE_VBI_CAPTURE struct v4l2_sliced_vbi_format sliced; // V4L2_BUF_TYPE_SLICED_VBI_CAPTURE diff --git a/v4l2-apps/util/v4l2-ctl.cpp b/v4l2-apps/util/v4l2-ctl.cpp index 0ce63bb1a..35d9f466b 100644 --- a/v4l2-apps/util/v4l2-ctl.cpp +++ b/v4l2-apps/util/v4l2-ctl.cpp @@ -678,6 +678,7 @@ static int printfmt(struct v4l2_format vfmt) switch (vfmt.type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: + case V4L2_BUF_TYPE_VIDEO_OUTPUT: printf("\tType : %s\n", buftype2s(vfmt.type).c_str()); printf("\tWidth/Height : %u/%u\n", vfmt.fmt.pix.width, vfmt.fmt.pix.height); printf("\tPixel Format : %s\n", fcc2s(vfmt.fmt.pix.pixelformat).c_str()); @@ -685,21 +686,17 @@ static int printfmt(struct v4l2_format vfmt) printf("\tBytes per Line: %u\n", vfmt.fmt.pix.bytesperline); printf("\tSize Image : %u\n", vfmt.fmt.pix.sizeimage); printf("\tColorspace : %s\n", colorspace2s(vfmt.fmt.pix.colorspace).c_str()); +#if 0 + /* Comment out until ABI breakage is resolved */ + if (vfmt.type == V4L2_BUF_TYPE_VIDEO_OUTPUT && + (capabilities & V4L2_CAP_VIDEO_OUTPUT_POS)) { + printf("\tLeft/Top : %d/%d\n", + vfmt.fmt.pix.left, vfmt.fmt.pix.top); + } +#endif if (vfmt.fmt.pix.priv) printf("\tCustom Info : %08x\n", vfmt.fmt.pix.priv); break; - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - printf("\tType : %s\n", buftype2s(vfmt.type).c_str()); - printf("\tWidth/Height : %u/%u\n", vfmt.fmt.pix_out.width, vfmt.fmt.pix_out.height); - printf("\tPixel Format : %s\n", fcc2s(vfmt.fmt.pix_out.pixelformat).c_str()); - printf("\tField : %s\n", field2s(vfmt.fmt.pix_out.field).c_str()); - printf("\tBytes per Line: %u\n", vfmt.fmt.pix_out.bytesperline); - printf("\tSize Image : %u\n", vfmt.fmt.pix_out.sizeimage); - printf("\tColorspace : %s\n", colorspace2s(vfmt.fmt.pix_out.colorspace).c_str()); - printf("\tLeft/Top : %d/%d\n", vfmt.fmt.pix_out.left, vfmt.fmt.pix_out.top); - if (vfmt.fmt.pix_out.priv) - printf("\tCustom Info : %08x\n", vfmt.fmt.pix_out.priv); - break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: case V4L2_BUF_TYPE_VIDEO_OVERLAY: printf("\tType : %s\n", buftype2s(vfmt.type).c_str()); @@ -863,6 +860,8 @@ static std::string cap2s(unsigned cap) s += "\t\tSliced VBI Output\n"; if (cap & V4L2_CAP_RDS_CAPTURE) s += "\t\tRDS Capture\n"; + if (cap & V4L2_CAP_VIDEO_OUTPUT_POS) + s += "\t\tVideo Output Position\n"; if (cap & V4L2_CAP_TUNER) s += "\t\tTuner\n"; if (cap & V4L2_CAP_AUDIO) @@ -1159,20 +1158,23 @@ int main(int argc, char **argv) }; switch (parse_subopt(&subs, subopts, &value)) { +#if 0 + /* Comment out until ABI breakage is resolved */ case 0: - vfmt_out.fmt.pix_out.top = strtol(value, 0L, 0); + vfmt_out.fmt.pix.top = strtol(value, 0L, 0); set_fmts_out |= FmtTop; break; case 1: - vfmt_out.fmt.pix_out.left = strtol(value, 0L, 0); + vfmt_out.fmt.pix.left = strtol(value, 0L, 0); set_fmts_out |= FmtLeft; break; +#endif case 2: - vfmt_out.fmt.pix_out.width = strtol(value, 0L, 0); + vfmt_out.fmt.pix.width = strtol(value, 0L, 0); set_fmts_out |= FmtWidth; break; case 3: - vfmt_out.fmt.pix_out.height = strtol(value, 0L, 0); + vfmt_out.fmt.pix.height = strtol(value, 0L, 0); set_fmts_out |= FmtHeight; break; } @@ -1556,14 +1558,17 @@ int main(int argc, char **argv) if (ioctl(fd, VIDIOC_G_FMT, &in_vfmt) < 0) fprintf(stderr, "ioctl: VIDIOC_G_FMT failed\n"); else { +#if 0 + /* Comment out until ABI breakage is resolved */ if (set_fmts_out & FmtTop) - in_vfmt.fmt.pix_out.top = vfmt_out.fmt.pix_out.top; + in_vfmt.fmt.pix.top = vfmt_out.fmt.pix.top; if (set_fmts_out & FmtLeft) - in_vfmt.fmt.pix_out.left = vfmt_out.fmt.pix_out.left; + in_vfmt.fmt.pix.left = vfmt_out.fmt.pix.left; +#endif if (set_fmts_out & FmtWidth) - in_vfmt.fmt.pix_out.width = vfmt_out.fmt.pix_out.width; + in_vfmt.fmt.pix.width = vfmt_out.fmt.pix.width; if (set_fmts_out & FmtHeight) - in_vfmt.fmt.pix_out.height = vfmt_out.fmt.pix_out.height; + in_vfmt.fmt.pix.height = vfmt_out.fmt.pix.height; if (ioctl(fd, VIDIOC_S_FMT, &in_vfmt) < 0) fprintf(stderr, "ioctl: VIDIOC_S_FMT failed\n"); } diff --git a/v4l2-apps/util/v4l2-dbg.cpp b/v4l2-apps/util/v4l2-dbg.cpp index 10c9a8927..6f373281e 100644 --- a/v4l2-apps/util/v4l2-dbg.cpp +++ b/v4l2-apps/util/v4l2-dbg.cpp @@ -160,6 +160,8 @@ static std::string cap2s(unsigned cap) s += "\t\tSliced VBI Output\n"; if (cap & V4L2_CAP_RDS_CAPTURE) s += "\t\tRDS Capture\n"; + if (cap & V4L2_CAP_VIDEO_OUTPUT_POS) + s += "\t\tVideo Output Position\n"; if (cap & V4L2_CAP_TUNER) s += "\t\tTuner\n"; if (cap & V4L2_CAP_AUDIO) -- cgit v1.2.3 From d94cd97f381d28b4469c33036bbc00473c617742 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 21 May 2007 11:15:09 -0300 Subject: Tuner-simple.c add suport for SECAM-BG with FI1216MF From: matthieu castet allow to use SECAM-BG with the FI1216MF tuner. The selection is done with the secam=B module argument. The default behaviour should be the same as before. Signed-off-by: Matthieu CASTET Signed-off-by: Andrew Morton Acked-by: Hartmut Hackmann Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/tuner-simple.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/linux/drivers/media/video/tuner-simple.c b/linux/drivers/media/video/tuner-simple.c index 16469d905..f91f8a690 100644 --- a/linux/drivers/media/video/tuner-simple.c +++ b/linux/drivers/media/video/tuner-simple.c @@ -230,9 +230,13 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) /* 0x01 -> ??? no change ??? */ /* 0x02 -> PAL BDGHI / SECAM L */ /* 0x04 -> ??? PAL others / SECAM others ??? */ - cb &= ~0x02; - if (t->std & V4L2_STD_SECAM) - cb |= 0x02; + cb &= ~0x03; + if (t->std & V4L2_STD_SECAM_L) //also valid for V4L2_STD_SECAM + cb |= PHILIPS_MF_SET_PAL_L; + else if (t->std & V4L2_STD_SECAM_LC) + cb |= PHILIPS_MF_SET_PAL_L2; + else /* V4L2_STD_B|V4L2_STD_GH */ + cb |= PHILIPS_MF_SET_BG; break; case TUNER_TEMIC_4046FM5: -- cgit v1.2.3 From 13b4e9409467fe56d3ecaa6ea96c582dfc2e41d7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 21 May 2007 11:39:21 -0300 Subject: Correct aliases for STD/L and STD/Lc From: Mauro Carvalho Chehab Some macros were using very weird names, like PAL/L (this std doesn't exist). Fixing it. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/tuner-simple.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/linux/drivers/media/video/tuner-simple.c b/linux/drivers/media/video/tuner-simple.c index f91f8a690..a4718b2f0 100644 --- a/linux/drivers/media/video/tuner-simple.c +++ b/linux/drivers/media/video/tuner-simple.c @@ -63,9 +63,9 @@ MODULE_PARM_DESC(offset,"Allows to specify an offset for tuner"); sound 2 33.16 - - NICAM 33.05 33.05 39.80 */ -#define PHILIPS_MF_SET_BG 0x01 /* Bit 2 must be zero, Bit 3 is system output */ -#define PHILIPS_MF_SET_PAL_L 0x03 // France -#define PHILIPS_MF_SET_PAL_L2 0x02 // L' +#define PHILIPS_MF_SET_STD_BG 0x01 /* Bit 2 must be zero, Bit 3 is system output */ +#define PHILIPS_MF_SET_STD_L 0x03 /* Used on Secam France */ +#define PHILIPS_MF_SET_STD_LC 0x02 /* Used on SECAM L' */ /* Control byte */ @@ -232,11 +232,11 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) /* 0x04 -> ??? PAL others / SECAM others ??? */ cb &= ~0x03; if (t->std & V4L2_STD_SECAM_L) //also valid for V4L2_STD_SECAM - cb |= PHILIPS_MF_SET_PAL_L; + cb |= PHILIPS_MF_SET_STD_L; else if (t->std & V4L2_STD_SECAM_LC) - cb |= PHILIPS_MF_SET_PAL_L2; + cb |= PHILIPS_MF_SET_STD_LC; else /* V4L2_STD_B|V4L2_STD_GH */ - cb |= PHILIPS_MF_SET_BG; + cb |= PHILIPS_MF_SET_STD_BG; break; case TUNER_TEMIC_4046FM5: -- cgit v1.2.3 From 40afb3b531b8e4eb61e48e01f536d02ec4182fa2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 21 May 2007 11:41:02 -0300 Subject: XXX From: Dmitry Torokhov V4L: SAA7134 - switch to using msecs_to_jiffies() Signed-off-by: Dmitry Torokhov Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/saa7134/saa7134-input.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/linux/drivers/media/video/saa7134/saa7134-input.c b/linux/drivers/media/video/saa7134/saa7134-input.c index 1b80a9c3a..c505076ae 100644 --- a/linux/drivers/media/video/saa7134/saa7134-input.c +++ b/linux/drivers/media/video/saa7134/saa7134-input.c @@ -154,21 +154,18 @@ void saa7134_input_irq(struct saa7134_dev *dev) static void saa7134_input_timer(unsigned long data) { - struct saa7134_dev *dev = (struct saa7134_dev*)data; + struct saa7134_dev *dev = (struct saa7134_dev *)data; struct card_ir *ir = dev->remote; - unsigned long timeout; build_key(dev); - timeout = jiffies + (ir->polling * HZ / 1000); - mod_timer(&ir->timer, timeout); + mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling)); } static void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir) { if (ir->polling) { - init_timer(&ir->timer); - ir->timer.function = saa7134_input_timer; - ir->timer.data = (unsigned long)dev; + setup_timer(&ir->timer, saa7134_input_timer, + (unsigned long)dev); ir->timer.expires = jiffies + HZ; add_timer(&ir->timer); } else if (ir->rc5_gpio) { -- cgit v1.2.3 From 37019a7d11c6cd4a51e9766830f6ed25e3e709d8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 21 May 2007 11:48:11 -0300 Subject: V4L: cx88 - switch to using msecs_to_jiffies() From: Dmitry Torokhov Signed-off-by: Dmitry Torokhov Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/cx88/cx88-input.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/linux/drivers/media/video/cx88/cx88-input.c b/linux/drivers/media/video/cx88/cx88-input.c index 6c712ecdd..a2e34e901 100644 --- a/linux/drivers/media/video/cx88/cx88-input.c +++ b/linux/drivers/media/video/cx88/cx88-input.c @@ -157,24 +157,20 @@ static void cx88_ir_work(struct work_struct *work) #else struct cx88_IR *ir = container_of(work, struct cx88_IR, work); #endif - unsigned long timeout; cx88_ir_handle_key(ir); - timeout = jiffies + (ir->polling * HZ / 1000); - mod_timer(&ir->timer, timeout); + mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling)); } static void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir) { if (ir->polling) { + setup_timer(&ir->timer, ir_timer, (unsigned long)ir); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) INIT_WORK(&ir->work, cx88_ir_work, ir); #else INIT_WORK(&ir->work, cx88_ir_work); #endif - init_timer(&ir->timer); - ir->timer.function = ir_timer; - ir->timer.data = (unsigned long)ir; schedule_work(&ir->work); } if (ir->sampling) { -- cgit v1.2.3 From cac5da1c7c1873320073fccdefc334fc34a745e3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 21 May 2007 11:51:11 -0300 Subject: V4L: ir-kbd-i2c - switch to using msecs_to_jiffies() From: Dmitry Torokhov Signed-off-by: Dmitry Torokhov Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/ir-kbd-i2c.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/linux/drivers/media/video/ir-kbd-i2c.c b/linux/drivers/media/video/ir-kbd-i2c.c index 8d0c49782..3333d0832 100644 --- a/linux/drivers/media/video/ir-kbd-i2c.c +++ b/linux/drivers/media/video/ir-kbd-i2c.c @@ -279,8 +279,9 @@ static void ir_work(struct work_struct *work) #else struct IR_i2c *ir = container_of(work, struct IR_i2c, work); #endif + ir_key_poll(ir); - mod_timer(&ir->timer, jiffies+HZ/10); + mod_timer(&ir->timer, jiffies + msecs_to_jiffies(100)); } /* ----------------------------------------------------------------------- */ -- cgit v1.2.3