media fixes for v4.16-rc4
-----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJamnteAAoJEAhfPr2O5OEVjKUP/03nggoRa29J66geB3LtTnsC lnQa2Dr6+fRji5eLsXC0su8o3Bf3P5KsyP9gfRrFQcsn68x6LiO6Ud4dL8yM6ZFh 4ShF8IYD1oNMT0CTq5bgfr34lyJRYsF0/FbXuO+XApOlL74JfstN4g3MFjBiojAQ B7URIw4snzLrpiJ+yHELL71tfPnzgUllWXKSDkql6Te+Gx1mYymDRyXdexlVKSiH hD/5mQ/6YJdAmFTHl0efvKGFEhfXK2l59I+gpRXgsupaSG+rV2RhjTeVPcWUcvCn P91/hpahtv2gHWZyEYpN9h1zkWFYFBt8exgnMAuo4YtFzAyMueeUowCrHvTL8P9V TSkLgFFsZBtrNmWsX1pw2JQJxq2qUXWZNBeUf326TQV9Z2WBeiikXiStdemR/IBQ ueVOH9yuLjEX9die8PCxU+O/hN0VTfKa0A59D+rTLBbj76LG+iAaK/NAVedJzv5v U3N0lPL0U8BIJ00VevktBfpB7FcsTBv2Wa/GHOgyCYZHW2NgUqj0cK4jfMogFNID MM5SgM4fv0D03p4KVLtu3d2+QDKmPjYBs6rAjEtU2eXvaoTzOPtciSb8As5MFxin xseliOBSVchJDRcKic0vMyMv2jDdvRcAEaDE/w+OsUyWPTixDNN1qOThp8OGEc6P 5P0nL89lvpf9StOl3WM5 =ypdv -----END PGP SIGNATURE----- Merge tag 'media/v4.16-3' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media Pull media fixes from Mauro Carvalho Chehab: - some build fixes with randconfigs - an m88ds3103 fix to prevent an OOPS if the chip doesn't provide the right version during probe (with can happen if the hardware hangs) - a potential out of array bounds reference in tvp5150 - some fixes and improvements in the DVB memory mapped API (added for kernel 4.16) * tag 'media/v4.16-3' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: media: vb2: Makefile: place vb2-trace together with vb2-core media: Don't let tvp5150_get_vbi() go out of vbi_ram_default array media: dvb: update buffer mmaped flags and frame counter media: dvb: add continuity error indicators for memory mapped buffers media: dmxdev: Fix the logic that enables DMA mmap support media: dmxdev: fix error code for invalid ioctls media: m88ds3103: don't call a non-initalized function media: au0828: add VIDEO_V4L2 dependency media: dvb: fix DVB_MMAP dependency media: dvb: fix DVB_MMAP symbol name media: videobuf2: fix build issues with vb2-trace media: videobuf2: Add VIDEOBUF2_V4L2 Kconfig option for VB2 V4L2 part
This commit is contained in:
commit
7cf901b355
|
@ -50,9 +50,15 @@ replace typedef dmx_filter_t :c:type:`dmx_filter`
|
||||||
replace typedef dmx_pes_type_t :c:type:`dmx_pes_type`
|
replace typedef dmx_pes_type_t :c:type:`dmx_pes_type`
|
||||||
replace typedef dmx_input_t :c:type:`dmx_input`
|
replace typedef dmx_input_t :c:type:`dmx_input`
|
||||||
|
|
||||||
ignore symbol DMX_OUT_DECODER
|
replace symbol DMX_BUFFER_FLAG_HAD_CRC32_DISCARD :c:type:`dmx_buffer_flags`
|
||||||
ignore symbol DMX_OUT_TAP
|
replace symbol DMX_BUFFER_FLAG_TEI :c:type:`dmx_buffer_flags`
|
||||||
ignore symbol DMX_OUT_TS_TAP
|
replace symbol DMX_BUFFER_PKT_COUNTER_MISMATCH :c:type:`dmx_buffer_flags`
|
||||||
ignore symbol DMX_OUT_TSDEMUX_TAP
|
replace symbol DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED :c:type:`dmx_buffer_flags`
|
||||||
|
replace symbol DMX_BUFFER_FLAG_DISCONTINUITY_INDICATOR :c:type:`dmx_buffer_flags`
|
||||||
|
|
||||||
|
replace symbol DMX_OUT_DECODER :c:type:`dmx_output`
|
||||||
|
replace symbol DMX_OUT_TAP :c:type:`dmx_output`
|
||||||
|
replace symbol DMX_OUT_TS_TAP :c:type:`dmx_output`
|
||||||
|
replace symbol DMX_OUT_TSDEMUX_TAP :c:type:`dmx_output`
|
||||||
|
|
||||||
replace ioctl DMX_DQBUF dmx_qbuf
|
replace ioctl DMX_DQBUF dmx_qbuf
|
||||||
|
|
|
@ -51,9 +51,10 @@ out to disk. Buffers remain locked until dequeued, until the
|
||||||
the device is closed.
|
the device is closed.
|
||||||
|
|
||||||
Applications call the ``DMX_DQBUF`` ioctl to dequeue a filled
|
Applications call the ``DMX_DQBUF`` ioctl to dequeue a filled
|
||||||
(capturing) buffer from the driver's outgoing queue. They just set the ``reserved`` field array to zero. When ``DMX_DQBUF`` is called with a
|
(capturing) buffer from the driver's outgoing queue.
|
||||||
pointer to this structure, the driver fills the remaining fields or
|
They just set the ``index`` field withe the buffer ID to be queued.
|
||||||
returns an error code.
|
When ``DMX_DQBUF`` is called with a pointer to struct :c:type:`dmx_buffer`,
|
||||||
|
the driver fills the remaining fields or returns an error code.
|
||||||
|
|
||||||
By default ``DMX_DQBUF`` blocks when no buffer is in the outgoing
|
By default ``DMX_DQBUF`` blocks when no buffer is in the outgoing
|
||||||
queue. When the ``O_NONBLOCK`` flag was given to the
|
queue. When the ``O_NONBLOCK`` flag was given to the
|
||||||
|
|
|
@ -147,6 +147,8 @@ config DVB_CORE
|
||||||
config DVB_MMAP
|
config DVB_MMAP
|
||||||
bool "Enable DVB memory-mapped API (EXPERIMENTAL)"
|
bool "Enable DVB memory-mapped API (EXPERIMENTAL)"
|
||||||
depends on DVB_CORE
|
depends on DVB_CORE
|
||||||
|
depends on VIDEO_V4L2=y || VIDEO_V4L2=DVB_CORE
|
||||||
|
select VIDEOBUF2_VMALLOC
|
||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
This option enables DVB experimental memory-mapped API, with
|
This option enables DVB experimental memory-mapped API, with
|
||||||
|
|
|
@ -3,6 +3,9 @@ config VIDEOBUF2_CORE
|
||||||
select DMA_SHARED_BUFFER
|
select DMA_SHARED_BUFFER
|
||||||
tristate
|
tristate
|
||||||
|
|
||||||
|
config VIDEOBUF2_V4L2
|
||||||
|
tristate
|
||||||
|
|
||||||
config VIDEOBUF2_MEMOPS
|
config VIDEOBUF2_MEMOPS
|
||||||
tristate
|
tristate
|
||||||
select FRAME_VECTOR
|
select FRAME_VECTOR
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
videobuf2-common-objs := videobuf2-core.o
|
||||||
|
|
||||||
obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-core.o videobuf2-v4l2.o
|
ifeq ($(CONFIG_TRACEPOINTS),y)
|
||||||
|
videobuf2-common-objs += vb2-trace.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-common.o
|
||||||
|
obj-$(CONFIG_VIDEOBUF2_V4L2) += videobuf2-v4l2.o
|
||||||
obj-$(CONFIG_VIDEOBUF2_MEMOPS) += videobuf2-memops.o
|
obj-$(CONFIG_VIDEOBUF2_MEMOPS) += videobuf2-memops.o
|
||||||
obj-$(CONFIG_VIDEOBUF2_VMALLOC) += videobuf2-vmalloc.o
|
obj-$(CONFIG_VIDEOBUF2_VMALLOC) += videobuf2-vmalloc.o
|
||||||
obj-$(CONFIG_VIDEOBUF2_DMA_CONTIG) += videobuf2-dma-contig.o
|
obj-$(CONFIG_VIDEOBUF2_DMA_CONTIG) += videobuf2-dma-contig.o
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
dvb-net-$(CONFIG_DVB_NET) := dvb_net.o
|
dvb-net-$(CONFIG_DVB_NET) := dvb_net.o
|
||||||
dvb-vb2-$(CONFIG_DVB_MMSP) := dvb_vb2.o
|
dvb-vb2-$(CONFIG_DVB_MMAP) := dvb_vb2.o
|
||||||
|
|
||||||
dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o \
|
dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o \
|
||||||
dvb_ca_en50221.o dvb_frontend.o \
|
dvb_ca_en50221.o dvb_frontend.o \
|
||||||
|
|
|
@ -128,11 +128,7 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
|
||||||
struct dvb_device *dvbdev = file->private_data;
|
struct dvb_device *dvbdev = file->private_data;
|
||||||
struct dmxdev *dmxdev = dvbdev->priv;
|
struct dmxdev *dmxdev = dvbdev->priv;
|
||||||
struct dmx_frontend *front;
|
struct dmx_frontend *front;
|
||||||
#ifndef DVB_MMAP
|
|
||||||
bool need_ringbuffer = false;
|
bool need_ringbuffer = false;
|
||||||
#else
|
|
||||||
const bool need_ringbuffer = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dprintk("%s\n", __func__);
|
dprintk("%s\n", __func__);
|
||||||
|
|
||||||
|
@ -144,17 +140,31 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef DVB_MMAP
|
dmxdev->may_do_mmap = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The logic here is a little tricky due to the ifdef.
|
||||||
|
*
|
||||||
|
* The ringbuffer is used for both read and mmap.
|
||||||
|
*
|
||||||
|
* It is not needed, however, on two situations:
|
||||||
|
* - Write devices (access with O_WRONLY);
|
||||||
|
* - For duplex device nodes, opened with O_RDWR.
|
||||||
|
*/
|
||||||
|
|
||||||
if ((file->f_flags & O_ACCMODE) == O_RDONLY)
|
if ((file->f_flags & O_ACCMODE) == O_RDONLY)
|
||||||
need_ringbuffer = true;
|
need_ringbuffer = true;
|
||||||
#else
|
else if ((file->f_flags & O_ACCMODE) == O_RDWR) {
|
||||||
if ((file->f_flags & O_ACCMODE) == O_RDWR) {
|
|
||||||
if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) {
|
if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) {
|
||||||
|
#ifdef CONFIG_DVB_MMAP
|
||||||
|
dmxdev->may_do_mmap = 1;
|
||||||
|
need_ringbuffer = true;
|
||||||
|
#else
|
||||||
mutex_unlock(&dmxdev->mutex);
|
mutex_unlock(&dmxdev->mutex);
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (need_ringbuffer) {
|
if (need_ringbuffer) {
|
||||||
void *mem;
|
void *mem;
|
||||||
|
@ -169,8 +179,9 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
dvb_ringbuffer_init(&dmxdev->dvr_buffer, mem, DVR_BUFFER_SIZE);
|
dvb_ringbuffer_init(&dmxdev->dvr_buffer, mem, DVR_BUFFER_SIZE);
|
||||||
dvb_vb2_init(&dmxdev->dvr_vb2_ctx, "dvr",
|
if (dmxdev->may_do_mmap)
|
||||||
file->f_flags & O_NONBLOCK);
|
dvb_vb2_init(&dmxdev->dvr_vb2_ctx, "dvr",
|
||||||
|
file->f_flags & O_NONBLOCK);
|
||||||
dvbdev->readers--;
|
dvbdev->readers--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,11 +211,6 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
struct dvb_device *dvbdev = file->private_data;
|
struct dvb_device *dvbdev = file->private_data;
|
||||||
struct dmxdev *dmxdev = dvbdev->priv;
|
struct dmxdev *dmxdev = dvbdev->priv;
|
||||||
#ifndef DVB_MMAP
|
|
||||||
bool need_ringbuffer = false;
|
|
||||||
#else
|
|
||||||
const bool need_ringbuffer = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mutex_lock(&dmxdev->mutex);
|
mutex_lock(&dmxdev->mutex);
|
||||||
|
|
||||||
|
@ -213,15 +219,14 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
|
||||||
dmxdev->demux->connect_frontend(dmxdev->demux,
|
dmxdev->demux->connect_frontend(dmxdev->demux,
|
||||||
dmxdev->dvr_orig_fe);
|
dmxdev->dvr_orig_fe);
|
||||||
}
|
}
|
||||||
#ifndef DVB_MMAP
|
|
||||||
if ((file->f_flags & O_ACCMODE) == O_RDONLY)
|
|
||||||
need_ringbuffer = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (need_ringbuffer) {
|
if (((file->f_flags & O_ACCMODE) == O_RDONLY) ||
|
||||||
if (dvb_vb2_is_streaming(&dmxdev->dvr_vb2_ctx))
|
dmxdev->may_do_mmap) {
|
||||||
dvb_vb2_stream_off(&dmxdev->dvr_vb2_ctx);
|
if (dmxdev->may_do_mmap) {
|
||||||
dvb_vb2_release(&dmxdev->dvr_vb2_ctx);
|
if (dvb_vb2_is_streaming(&dmxdev->dvr_vb2_ctx))
|
||||||
|
dvb_vb2_stream_off(&dmxdev->dvr_vb2_ctx);
|
||||||
|
dvb_vb2_release(&dmxdev->dvr_vb2_ctx);
|
||||||
|
}
|
||||||
dvbdev->readers++;
|
dvbdev->readers++;
|
||||||
if (dmxdev->dvr_buffer.data) {
|
if (dmxdev->dvr_buffer.data) {
|
||||||
void *mem = dmxdev->dvr_buffer.data;
|
void *mem = dmxdev->dvr_buffer.data;
|
||||||
|
@ -380,7 +385,8 @@ static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter)
|
||||||
|
|
||||||
static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
|
static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
|
||||||
const u8 *buffer2, size_t buffer2_len,
|
const u8 *buffer2, size_t buffer2_len,
|
||||||
struct dmx_section_filter *filter)
|
struct dmx_section_filter *filter,
|
||||||
|
u32 *buffer_flags)
|
||||||
{
|
{
|
||||||
struct dmxdev_filter *dmxdevfilter = filter->priv;
|
struct dmxdev_filter *dmxdevfilter = filter->priv;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -399,10 +405,12 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
|
||||||
dprintk("section callback %*ph\n", 6, buffer1);
|
dprintk("section callback %*ph\n", 6, buffer1);
|
||||||
if (dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx)) {
|
if (dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx)) {
|
||||||
ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx,
|
ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx,
|
||||||
buffer1, buffer1_len);
|
buffer1, buffer1_len,
|
||||||
|
buffer_flags);
|
||||||
if (ret == buffer1_len)
|
if (ret == buffer1_len)
|
||||||
ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx,
|
ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx,
|
||||||
buffer2, buffer2_len);
|
buffer2, buffer2_len,
|
||||||
|
buffer_flags);
|
||||||
} else {
|
} else {
|
||||||
ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer,
|
ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer,
|
||||||
buffer1, buffer1_len);
|
buffer1, buffer1_len);
|
||||||
|
@ -422,11 +430,12 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
|
||||||
|
|
||||||
static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
|
static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
|
||||||
const u8 *buffer2, size_t buffer2_len,
|
const u8 *buffer2, size_t buffer2_len,
|
||||||
struct dmx_ts_feed *feed)
|
struct dmx_ts_feed *feed,
|
||||||
|
u32 *buffer_flags)
|
||||||
{
|
{
|
||||||
struct dmxdev_filter *dmxdevfilter = feed->priv;
|
struct dmxdev_filter *dmxdevfilter = feed->priv;
|
||||||
struct dvb_ringbuffer *buffer;
|
struct dvb_ringbuffer *buffer;
|
||||||
#ifdef DVB_MMAP
|
#ifdef CONFIG_DVB_MMAP
|
||||||
struct dvb_vb2_ctx *ctx;
|
struct dvb_vb2_ctx *ctx;
|
||||||
#endif
|
#endif
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -440,20 +449,22 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
|
||||||
if (dmxdevfilter->params.pes.output == DMX_OUT_TAP ||
|
if (dmxdevfilter->params.pes.output == DMX_OUT_TAP ||
|
||||||
dmxdevfilter->params.pes.output == DMX_OUT_TSDEMUX_TAP) {
|
dmxdevfilter->params.pes.output == DMX_OUT_TSDEMUX_TAP) {
|
||||||
buffer = &dmxdevfilter->buffer;
|
buffer = &dmxdevfilter->buffer;
|
||||||
#ifdef DVB_MMAP
|
#ifdef CONFIG_DVB_MMAP
|
||||||
ctx = &dmxdevfilter->vb2_ctx;
|
ctx = &dmxdevfilter->vb2_ctx;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
buffer = &dmxdevfilter->dev->dvr_buffer;
|
buffer = &dmxdevfilter->dev->dvr_buffer;
|
||||||
#ifdef DVB_MMAP
|
#ifdef CONFIG_DVB_MMAP
|
||||||
ctx = &dmxdevfilter->dev->dvr_vb2_ctx;
|
ctx = &dmxdevfilter->dev->dvr_vb2_ctx;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dvb_vb2_is_streaming(ctx)) {
|
if (dvb_vb2_is_streaming(ctx)) {
|
||||||
ret = dvb_vb2_fill_buffer(ctx, buffer1, buffer1_len);
|
ret = dvb_vb2_fill_buffer(ctx, buffer1, buffer1_len,
|
||||||
|
buffer_flags);
|
||||||
if (ret == buffer1_len)
|
if (ret == buffer1_len)
|
||||||
ret = dvb_vb2_fill_buffer(ctx, buffer2, buffer2_len);
|
ret = dvb_vb2_fill_buffer(ctx, buffer2, buffer2_len,
|
||||||
|
buffer_flags);
|
||||||
} else {
|
} else {
|
||||||
if (buffer->error) {
|
if (buffer->error) {
|
||||||
spin_unlock(&dmxdevfilter->dev->lock);
|
spin_unlock(&dmxdevfilter->dev->lock);
|
||||||
|
@ -802,6 +813,12 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
|
||||||
mutex_init(&dmxdevfilter->mutex);
|
mutex_init(&dmxdevfilter->mutex);
|
||||||
file->private_data = dmxdevfilter;
|
file->private_data = dmxdevfilter;
|
||||||
|
|
||||||
|
#ifdef CONFIG_DVB_MMAP
|
||||||
|
dmxdev->may_do_mmap = 1;
|
||||||
|
#else
|
||||||
|
dmxdev->may_do_mmap = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192);
|
dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192);
|
||||||
dvb_vb2_init(&dmxdevfilter->vb2_ctx, "demux_filter",
|
dvb_vb2_init(&dmxdevfilter->vb2_ctx, "demux_filter",
|
||||||
file->f_flags & O_NONBLOCK);
|
file->f_flags & O_NONBLOCK);
|
||||||
|
@ -1111,7 +1128,7 @@ static int dvb_demux_do_ioctl(struct file *file,
|
||||||
mutex_unlock(&dmxdevfilter->mutex);
|
mutex_unlock(&dmxdevfilter->mutex);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef DVB_MMAP
|
#ifdef CONFIG_DVB_MMAP
|
||||||
case DMX_REQBUFS:
|
case DMX_REQBUFS:
|
||||||
if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
|
if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
|
||||||
mutex_unlock(&dmxdev->mutex);
|
mutex_unlock(&dmxdev->mutex);
|
||||||
|
@ -1160,7 +1177,7 @@ static int dvb_demux_do_ioctl(struct file *file,
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
ret = -EINVAL;
|
ret = -ENOTTY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mutex_unlock(&dmxdev->mutex);
|
mutex_unlock(&dmxdev->mutex);
|
||||||
|
@ -1199,13 +1216,16 @@ static __poll_t dvb_demux_poll(struct file *file, poll_table *wait)
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DVB_MMAP
|
#ifdef CONFIG_DVB_MMAP
|
||||||
static int dvb_demux_mmap(struct file *file, struct vm_area_struct *vma)
|
static int dvb_demux_mmap(struct file *file, struct vm_area_struct *vma)
|
||||||
{
|
{
|
||||||
struct dmxdev_filter *dmxdevfilter = file->private_data;
|
struct dmxdev_filter *dmxdevfilter = file->private_data;
|
||||||
struct dmxdev *dmxdev = dmxdevfilter->dev;
|
struct dmxdev *dmxdev = dmxdevfilter->dev;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (!dmxdev->may_do_mmap)
|
||||||
|
return -ENOTTY;
|
||||||
|
|
||||||
if (mutex_lock_interruptible(&dmxdev->mutex))
|
if (mutex_lock_interruptible(&dmxdev->mutex))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
|
@ -1249,7 +1269,7 @@ static const struct file_operations dvb_demux_fops = {
|
||||||
.release = dvb_demux_release,
|
.release = dvb_demux_release,
|
||||||
.poll = dvb_demux_poll,
|
.poll = dvb_demux_poll,
|
||||||
.llseek = default_llseek,
|
.llseek = default_llseek,
|
||||||
#ifdef DVB_MMAP
|
#ifdef CONFIG_DVB_MMAP
|
||||||
.mmap = dvb_demux_mmap,
|
.mmap = dvb_demux_mmap,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
@ -1280,7 +1300,7 @@ static int dvb_dvr_do_ioctl(struct file *file,
|
||||||
ret = dvb_dvr_set_buffer_size(dmxdev, arg);
|
ret = dvb_dvr_set_buffer_size(dmxdev, arg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef DVB_MMAP
|
#ifdef CONFIG_DVB_MMAP
|
||||||
case DMX_REQBUFS:
|
case DMX_REQBUFS:
|
||||||
ret = dvb_vb2_reqbufs(&dmxdev->dvr_vb2_ctx, parg);
|
ret = dvb_vb2_reqbufs(&dmxdev->dvr_vb2_ctx, parg);
|
||||||
break;
|
break;
|
||||||
|
@ -1304,7 +1324,7 @@ static int dvb_dvr_do_ioctl(struct file *file,
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
ret = -EINVAL;
|
ret = -ENOTTY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mutex_unlock(&dmxdev->mutex);
|
mutex_unlock(&dmxdev->mutex);
|
||||||
|
@ -1322,11 +1342,6 @@ static __poll_t dvb_dvr_poll(struct file *file, poll_table *wait)
|
||||||
struct dvb_device *dvbdev = file->private_data;
|
struct dvb_device *dvbdev = file->private_data;
|
||||||
struct dmxdev *dmxdev = dvbdev->priv;
|
struct dmxdev *dmxdev = dvbdev->priv;
|
||||||
__poll_t mask = 0;
|
__poll_t mask = 0;
|
||||||
#ifndef DVB_MMAP
|
|
||||||
bool need_ringbuffer = false;
|
|
||||||
#else
|
|
||||||
const bool need_ringbuffer = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dprintk("%s\n", __func__);
|
dprintk("%s\n", __func__);
|
||||||
|
|
||||||
|
@ -1337,11 +1352,8 @@ static __poll_t dvb_dvr_poll(struct file *file, poll_table *wait)
|
||||||
|
|
||||||
poll_wait(file, &dmxdev->dvr_buffer.queue, wait);
|
poll_wait(file, &dmxdev->dvr_buffer.queue, wait);
|
||||||
|
|
||||||
#ifndef DVB_MMAP
|
if (((file->f_flags & O_ACCMODE) == O_RDONLY) ||
|
||||||
if ((file->f_flags & O_ACCMODE) == O_RDONLY)
|
dmxdev->may_do_mmap) {
|
||||||
need_ringbuffer = true;
|
|
||||||
#endif
|
|
||||||
if (need_ringbuffer) {
|
|
||||||
if (dmxdev->dvr_buffer.error)
|
if (dmxdev->dvr_buffer.error)
|
||||||
mask |= (EPOLLIN | EPOLLRDNORM | EPOLLPRI | EPOLLERR);
|
mask |= (EPOLLIN | EPOLLRDNORM | EPOLLPRI | EPOLLERR);
|
||||||
|
|
||||||
|
@ -1353,13 +1365,16 @@ static __poll_t dvb_dvr_poll(struct file *file, poll_table *wait)
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DVB_MMAP
|
#ifdef CONFIG_DVB_MMAP
|
||||||
static int dvb_dvr_mmap(struct file *file, struct vm_area_struct *vma)
|
static int dvb_dvr_mmap(struct file *file, struct vm_area_struct *vma)
|
||||||
{
|
{
|
||||||
struct dvb_device *dvbdev = file->private_data;
|
struct dvb_device *dvbdev = file->private_data;
|
||||||
struct dmxdev *dmxdev = dvbdev->priv;
|
struct dmxdev *dmxdev = dvbdev->priv;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (!dmxdev->may_do_mmap)
|
||||||
|
return -ENOTTY;
|
||||||
|
|
||||||
if (dmxdev->exit)
|
if (dmxdev->exit)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
@ -1381,7 +1396,7 @@ static const struct file_operations dvb_dvr_fops = {
|
||||||
.release = dvb_dvr_release,
|
.release = dvb_dvr_release,
|
||||||
.poll = dvb_dvr_poll,
|
.poll = dvb_dvr_poll,
|
||||||
.llseek = default_llseek,
|
.llseek = default_llseek,
|
||||||
#ifdef DVB_MMAP
|
#ifdef CONFIG_DVB_MMAP
|
||||||
.mmap = dvb_dvr_mmap,
|
.mmap = dvb_dvr_mmap,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -55,6 +55,17 @@ MODULE_PARM_DESC(dvb_demux_feed_err_pkts,
|
||||||
dprintk(x); \
|
dprintk(x); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
|
||||||
|
# define dprintk_sect_loss(x...) dprintk(x)
|
||||||
|
#else
|
||||||
|
# define dprintk_sect_loss(x...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define set_buf_flags(__feed, __flag) \
|
||||||
|
do { \
|
||||||
|
(__feed)->buffer_flags |= (__flag); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* static inlined helper functions
|
* static inlined helper functions
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
@ -104,31 +115,30 @@ static inline int dvb_dmx_swfilter_payload(struct dvb_demux_feed *feed,
|
||||||
{
|
{
|
||||||
int count = payload(buf);
|
int count = payload(buf);
|
||||||
int p;
|
int p;
|
||||||
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
|
|
||||||
int ccok;
|
int ccok;
|
||||||
u8 cc;
|
u8 cc;
|
||||||
#endif
|
|
||||||
|
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
p = 188 - count;
|
p = 188 - count;
|
||||||
|
|
||||||
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
|
|
||||||
cc = buf[3] & 0x0f;
|
cc = buf[3] & 0x0f;
|
||||||
ccok = ((feed->cc + 1) & 0x0f) == cc;
|
ccok = ((feed->cc + 1) & 0x0f) == cc;
|
||||||
feed->cc = cc;
|
feed->cc = cc;
|
||||||
if (!ccok)
|
if (!ccok) {
|
||||||
dprintk("missed packet: %d instead of %d!\n",
|
set_buf_flags(feed, DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
|
||||||
cc, (feed->cc + 1) & 0x0f);
|
dprintk_sect_loss("missed packet: %d instead of %d!\n",
|
||||||
#endif
|
cc, (feed->cc + 1) & 0x0f);
|
||||||
|
}
|
||||||
|
|
||||||
if (buf[1] & 0x40) // PUSI ?
|
if (buf[1] & 0x40) // PUSI ?
|
||||||
feed->peslen = 0xfffa;
|
feed->peslen = 0xfffa;
|
||||||
|
|
||||||
feed->peslen += count;
|
feed->peslen += count;
|
||||||
|
|
||||||
return feed->cb.ts(&buf[p], count, NULL, 0, &feed->feed.ts);
|
return feed->cb.ts(&buf[p], count, NULL, 0, &feed->feed.ts,
|
||||||
|
&feed->buffer_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dvb_dmx_swfilter_sectionfilter(struct dvb_demux_feed *feed,
|
static int dvb_dmx_swfilter_sectionfilter(struct dvb_demux_feed *feed,
|
||||||
|
@ -150,7 +160,7 @@ static int dvb_dmx_swfilter_sectionfilter(struct dvb_demux_feed *feed,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return feed->cb.sec(feed->feed.sec.secbuf, feed->feed.sec.seclen,
|
return feed->cb.sec(feed->feed.sec.secbuf, feed->feed.sec.seclen,
|
||||||
NULL, 0, &f->filter);
|
NULL, 0, &f->filter, &feed->buffer_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int dvb_dmx_swfilter_section_feed(struct dvb_demux_feed *feed)
|
static inline int dvb_dmx_swfilter_section_feed(struct dvb_demux_feed *feed)
|
||||||
|
@ -169,8 +179,10 @@ static inline int dvb_dmx_swfilter_section_feed(struct dvb_demux_feed *feed)
|
||||||
if (sec->check_crc) {
|
if (sec->check_crc) {
|
||||||
section_syntax_indicator = ((sec->secbuf[1] & 0x80) != 0);
|
section_syntax_indicator = ((sec->secbuf[1] & 0x80) != 0);
|
||||||
if (section_syntax_indicator &&
|
if (section_syntax_indicator &&
|
||||||
demux->check_crc32(feed, sec->secbuf, sec->seclen))
|
demux->check_crc32(feed, sec->secbuf, sec->seclen)) {
|
||||||
|
set_buf_flags(feed, DMX_BUFFER_FLAG_HAD_CRC32_DISCARD);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -187,7 +199,6 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
|
||||||
{
|
{
|
||||||
struct dmx_section_feed *sec = &feed->feed.sec;
|
struct dmx_section_feed *sec = &feed->feed.sec;
|
||||||
|
|
||||||
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
|
|
||||||
if (sec->secbufp < sec->tsfeedp) {
|
if (sec->secbufp < sec->tsfeedp) {
|
||||||
int n = sec->tsfeedp - sec->secbufp;
|
int n = sec->tsfeedp - sec->secbufp;
|
||||||
|
|
||||||
|
@ -197,12 +208,13 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
|
||||||
* but just first and last.
|
* but just first and last.
|
||||||
*/
|
*/
|
||||||
if (sec->secbuf[0] != 0xff || sec->secbuf[n - 1] != 0xff) {
|
if (sec->secbuf[0] != 0xff || sec->secbuf[n - 1] != 0xff) {
|
||||||
dprintk("section ts padding loss: %d/%d\n",
|
set_buf_flags(feed,
|
||||||
n, sec->tsfeedp);
|
DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
|
||||||
dprintk("pad data: %*ph\n", n, sec->secbuf);
|
dprintk_sect_loss("section ts padding loss: %d/%d\n",
|
||||||
|
n, sec->tsfeedp);
|
||||||
|
dprintk_sect_loss("pad data: %*ph\n", n, sec->secbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
sec->tsfeedp = sec->secbufp = sec->seclen = 0;
|
sec->tsfeedp = sec->secbufp = sec->seclen = 0;
|
||||||
sec->secbuf = sec->secbuf_base;
|
sec->secbuf = sec->secbuf_base;
|
||||||
|
@ -237,11 +249,10 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE) {
|
if (sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE) {
|
||||||
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
|
set_buf_flags(feed, DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
|
||||||
dprintk("section buffer full loss: %d/%d\n",
|
dprintk_sect_loss("section buffer full loss: %d/%d\n",
|
||||||
sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE,
|
sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE,
|
||||||
DMX_MAX_SECFEED_SIZE);
|
DMX_MAX_SECFEED_SIZE);
|
||||||
#endif
|
|
||||||
len = DMX_MAX_SECFEED_SIZE - sec->tsfeedp;
|
len = DMX_MAX_SECFEED_SIZE - sec->tsfeedp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,12 +280,13 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
|
||||||
sec->seclen = seclen;
|
sec->seclen = seclen;
|
||||||
sec->crc_val = ~0;
|
sec->crc_val = ~0;
|
||||||
/* dump [secbuf .. secbuf+seclen) */
|
/* dump [secbuf .. secbuf+seclen) */
|
||||||
if (feed->pusi_seen)
|
if (feed->pusi_seen) {
|
||||||
dvb_dmx_swfilter_section_feed(feed);
|
dvb_dmx_swfilter_section_feed(feed);
|
||||||
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
|
} else {
|
||||||
else
|
set_buf_flags(feed,
|
||||||
dprintk("pusi not seen, discarding section data\n");
|
DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
|
||||||
#endif
|
dprintk_sect_loss("pusi not seen, discarding section data\n");
|
||||||
|
}
|
||||||
sec->secbufp += seclen; /* secbufp and secbuf moving together is */
|
sec->secbufp += seclen; /* secbufp and secbuf moving together is */
|
||||||
sec->secbuf += seclen; /* redundant but saves pointer arithmetic */
|
sec->secbuf += seclen; /* redundant but saves pointer arithmetic */
|
||||||
}
|
}
|
||||||
|
@ -307,18 +319,22 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ccok || dc_i) {
|
if (!ccok || dc_i) {
|
||||||
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
|
if (dc_i) {
|
||||||
if (dc_i)
|
set_buf_flags(feed,
|
||||||
dprintk("%d frame with disconnect indicator\n",
|
DMX_BUFFER_FLAG_DISCONTINUITY_INDICATOR);
|
||||||
|
dprintk_sect_loss("%d frame with disconnect indicator\n",
|
||||||
cc);
|
cc);
|
||||||
else
|
} else {
|
||||||
dprintk("discontinuity: %d instead of %d. %d bytes lost\n",
|
set_buf_flags(feed,
|
||||||
|
DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
|
||||||
|
dprintk_sect_loss("discontinuity: %d instead of %d. %d bytes lost\n",
|
||||||
cc, (feed->cc + 1) & 0x0f, count + 4);
|
cc, (feed->cc + 1) & 0x0f, count + 4);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* those bytes under sume circumstances will again be reported
|
* those bytes under some circumstances will again be reported
|
||||||
* in the following dvb_dmx_swfilter_section_new
|
* in the following dvb_dmx_swfilter_section_new
|
||||||
*/
|
*/
|
||||||
#endif
|
|
||||||
/*
|
/*
|
||||||
* Discontinuity detected. Reset pusi_seen to
|
* Discontinuity detected. Reset pusi_seen to
|
||||||
* stop feeding of suspicious data until next PUSI=1 arrives
|
* stop feeding of suspicious data until next PUSI=1 arrives
|
||||||
|
@ -326,6 +342,7 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
|
||||||
* FIXME: does it make sense if the MPEG-TS is the one
|
* FIXME: does it make sense if the MPEG-TS is the one
|
||||||
* reporting discontinuity?
|
* reporting discontinuity?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
feed->pusi_seen = false;
|
feed->pusi_seen = false;
|
||||||
dvb_dmx_swfilter_section_new(feed);
|
dvb_dmx_swfilter_section_new(feed);
|
||||||
}
|
}
|
||||||
|
@ -345,11 +362,11 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
|
||||||
dvb_dmx_swfilter_section_new(feed);
|
dvb_dmx_swfilter_section_new(feed);
|
||||||
dvb_dmx_swfilter_section_copy_dump(feed, after,
|
dvb_dmx_swfilter_section_copy_dump(feed, after,
|
||||||
after_len);
|
after_len);
|
||||||
|
} else if (count > 0) {
|
||||||
|
set_buf_flags(feed,
|
||||||
|
DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
|
||||||
|
dprintk_sect_loss("PUSI=1 but %d bytes lost\n", count);
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
|
|
||||||
else if (count > 0)
|
|
||||||
dprintk("PUSI=1 but %d bytes lost\n", count);
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
/* PUSI=0 (is not set), no section boundary */
|
/* PUSI=0 (is not set), no section boundary */
|
||||||
dvb_dmx_swfilter_section_copy_dump(feed, &buf[p], count);
|
dvb_dmx_swfilter_section_copy_dump(feed, &buf[p], count);
|
||||||
|
@ -369,7 +386,8 @@ static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed,
|
||||||
if (feed->ts_type & TS_PAYLOAD_ONLY)
|
if (feed->ts_type & TS_PAYLOAD_ONLY)
|
||||||
dvb_dmx_swfilter_payload(feed, buf);
|
dvb_dmx_swfilter_payload(feed, buf);
|
||||||
else
|
else
|
||||||
feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts);
|
feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts,
|
||||||
|
&feed->buffer_flags);
|
||||||
}
|
}
|
||||||
/* Used only on full-featured devices */
|
/* Used only on full-featured devices */
|
||||||
if (feed->ts_type & TS_DECODER)
|
if (feed->ts_type & TS_DECODER)
|
||||||
|
@ -430,6 +448,11 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf[1] & 0x80) {
|
if (buf[1] & 0x80) {
|
||||||
|
list_for_each_entry(feed, &demux->feed_list, list_head) {
|
||||||
|
if ((feed->pid != pid) && (feed->pid != 0x2000))
|
||||||
|
continue;
|
||||||
|
set_buf_flags(feed, DMX_BUFFER_FLAG_TEI);
|
||||||
|
}
|
||||||
dprintk_tscheck("TEI detected. PID=0x%x data1=0x%x\n",
|
dprintk_tscheck("TEI detected. PID=0x%x data1=0x%x\n",
|
||||||
pid, buf[1]);
|
pid, buf[1]);
|
||||||
/* data in this packet can't be trusted - drop it unless
|
/* data in this packet can't be trusted - drop it unless
|
||||||
|
@ -445,6 +468,13 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
|
||||||
(demux->cnt_storage[pid] + 1) & 0xf;
|
(demux->cnt_storage[pid] + 1) & 0xf;
|
||||||
|
|
||||||
if ((buf[3] & 0xf) != demux->cnt_storage[pid]) {
|
if ((buf[3] & 0xf) != demux->cnt_storage[pid]) {
|
||||||
|
list_for_each_entry(feed, &demux->feed_list, list_head) {
|
||||||
|
if ((feed->pid != pid) && (feed->pid != 0x2000))
|
||||||
|
continue;
|
||||||
|
set_buf_flags(feed,
|
||||||
|
DMX_BUFFER_PKT_COUNTER_MISMATCH);
|
||||||
|
}
|
||||||
|
|
||||||
dprintk_tscheck("TS packet counter mismatch. PID=0x%x expected 0x%x got 0x%x\n",
|
dprintk_tscheck("TS packet counter mismatch. PID=0x%x expected 0x%x got 0x%x\n",
|
||||||
pid, demux->cnt_storage[pid],
|
pid, demux->cnt_storage[pid],
|
||||||
buf[3] & 0xf);
|
buf[3] & 0xf);
|
||||||
|
@ -466,7 +496,8 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
|
||||||
if (feed->pid == pid)
|
if (feed->pid == pid)
|
||||||
dvb_dmx_swfilter_packet_type(feed, buf);
|
dvb_dmx_swfilter_packet_type(feed, buf);
|
||||||
else if (feed->pid == 0x2000)
|
else if (feed->pid == 0x2000)
|
||||||
feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts);
|
feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts,
|
||||||
|
&feed->buffer_flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -585,7 +616,8 @@ void dvb_dmx_swfilter_raw(struct dvb_demux *demux, const u8 *buf, size_t count)
|
||||||
|
|
||||||
spin_lock_irqsave(&demux->lock, flags);
|
spin_lock_irqsave(&demux->lock, flags);
|
||||||
|
|
||||||
demux->feed->cb.ts(buf, count, NULL, 0, &demux->feed->feed.ts);
|
demux->feed->cb.ts(buf, count, NULL, 0, &demux->feed->feed.ts,
|
||||||
|
&demux->feed->buffer_flags);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&demux->lock, flags);
|
spin_unlock_irqrestore(&demux->lock, flags);
|
||||||
}
|
}
|
||||||
|
@ -785,6 +817,7 @@ static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx,
|
||||||
feed->demux = demux;
|
feed->demux = demux;
|
||||||
feed->pid = 0xffff;
|
feed->pid = 0xffff;
|
||||||
feed->peslen = 0xfffa;
|
feed->peslen = 0xfffa;
|
||||||
|
feed->buffer_flags = 0;
|
||||||
|
|
||||||
(*ts_feed) = &feed->feed.ts;
|
(*ts_feed) = &feed->feed.ts;
|
||||||
(*ts_feed)->parent = dmx;
|
(*ts_feed)->parent = dmx;
|
||||||
|
@ -1042,6 +1075,7 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux,
|
||||||
dvbdmxfeed->cb.sec = callback;
|
dvbdmxfeed->cb.sec = callback;
|
||||||
dvbdmxfeed->demux = dvbdmx;
|
dvbdmxfeed->demux = dvbdmx;
|
||||||
dvbdmxfeed->pid = 0xffff;
|
dvbdmxfeed->pid = 0xffff;
|
||||||
|
dvbdmxfeed->buffer_flags = 0;
|
||||||
dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base;
|
dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base;
|
||||||
dvbdmxfeed->feed.sec.secbufp = dvbdmxfeed->feed.sec.seclen = 0;
|
dvbdmxfeed->feed.sec.secbufp = dvbdmxfeed->feed.sec.seclen = 0;
|
||||||
dvbdmxfeed->feed.sec.tsfeedp = 0;
|
dvbdmxfeed->feed.sec.tsfeedp = 0;
|
||||||
|
|
|
@ -883,7 +883,8 @@ static void dvb_net_ule(struct net_device *dev, const u8 *buf, size_t buf_len)
|
||||||
|
|
||||||
static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len,
|
static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len,
|
||||||
const u8 *buffer2, size_t buffer2_len,
|
const u8 *buffer2, size_t buffer2_len,
|
||||||
struct dmx_ts_feed *feed)
|
struct dmx_ts_feed *feed,
|
||||||
|
u32 *buffer_flags)
|
||||||
{
|
{
|
||||||
struct net_device *dev = feed->priv;
|
struct net_device *dev = feed->priv;
|
||||||
|
|
||||||
|
@ -992,7 +993,7 @@ static void dvb_net_sec(struct net_device *dev,
|
||||||
|
|
||||||
static int dvb_net_sec_callback(const u8 *buffer1, size_t buffer1_len,
|
static int dvb_net_sec_callback(const u8 *buffer1, size_t buffer1_len,
|
||||||
const u8 *buffer2, size_t buffer2_len,
|
const u8 *buffer2, size_t buffer2_len,
|
||||||
struct dmx_section_filter *filter)
|
struct dmx_section_filter *filter, u32 *buffer_flags)
|
||||||
{
|
{
|
||||||
struct net_device *dev = filter->priv;
|
struct net_device *dev = filter->priv;
|
||||||
|
|
||||||
|
|
|
@ -256,7 +256,8 @@ int dvb_vb2_is_streaming(struct dvb_vb2_ctx *ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx,
|
int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx,
|
||||||
const unsigned char *src, int len)
|
const unsigned char *src, int len,
|
||||||
|
enum dmx_buffer_flags *buffer_flags)
|
||||||
{
|
{
|
||||||
unsigned long flags = 0;
|
unsigned long flags = 0;
|
||||||
void *vbuf = NULL;
|
void *vbuf = NULL;
|
||||||
|
@ -264,15 +265,17 @@ int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx,
|
||||||
unsigned char *psrc = (unsigned char *)src;
|
unsigned char *psrc = (unsigned char *)src;
|
||||||
int ll = 0;
|
int ll = 0;
|
||||||
|
|
||||||
dprintk(3, "[%s] %d bytes are rcvd\n", ctx->name, len);
|
/*
|
||||||
if (!src) {
|
* normal case: This func is called twice from demux driver
|
||||||
dprintk(3, "[%s]:NULL pointer src\n", ctx->name);
|
* one with valid src pointer, second time with NULL pointer
|
||||||
/**normal case: This func is called twice from demux driver
|
*/
|
||||||
* once with valid src pointer, second time with NULL pointer
|
if (!src || !len)
|
||||||
*/
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
spin_lock_irqsave(&ctx->slock, flags);
|
spin_lock_irqsave(&ctx->slock, flags);
|
||||||
|
if (buffer_flags && *buffer_flags) {
|
||||||
|
ctx->flags |= *buffer_flags;
|
||||||
|
*buffer_flags = 0;
|
||||||
|
}
|
||||||
while (todo) {
|
while (todo) {
|
||||||
if (!ctx->buf) {
|
if (!ctx->buf) {
|
||||||
if (list_empty(&ctx->dvb_q)) {
|
if (list_empty(&ctx->dvb_q)) {
|
||||||
|
@ -395,6 +398,7 @@ int dvb_vb2_qbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
|
||||||
|
|
||||||
int dvb_vb2_dqbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
|
int dvb_vb2_dqbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
|
||||||
{
|
{
|
||||||
|
unsigned long flags;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = vb2_core_dqbuf(&ctx->vb_q, &b->index, b, ctx->nonblocking);
|
ret = vb2_core_dqbuf(&ctx->vb_q, &b->index, b, ctx->nonblocking);
|
||||||
|
@ -402,7 +406,16 @@ int dvb_vb2_dqbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
|
||||||
dprintk(1, "[%s] errno=%d\n", ctx->name, ret);
|
dprintk(1, "[%s] errno=%d\n", ctx->name, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
dprintk(5, "[%s] index=%d\n", ctx->name, b->index);
|
|
||||||
|
spin_lock_irqsave(&ctx->slock, flags);
|
||||||
|
b->count = ctx->count++;
|
||||||
|
b->flags = ctx->flags;
|
||||||
|
ctx->flags = 0;
|
||||||
|
spin_unlock_irqrestore(&ctx->slock, flags);
|
||||||
|
|
||||||
|
dprintk(5, "[%s] index=%d, count=%d, flags=%d\n",
|
||||||
|
ctx->name, b->index, ctx->count, b->flags);
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1262,11 +1262,12 @@ static int m88ds3103_select(struct i2c_mux_core *muxc, u32 chan)
|
||||||
* New users must use I2C client binding directly!
|
* New users must use I2C client binding directly!
|
||||||
*/
|
*/
|
||||||
struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg,
|
struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg,
|
||||||
struct i2c_adapter *i2c, struct i2c_adapter **tuner_i2c_adapter)
|
struct i2c_adapter *i2c,
|
||||||
|
struct i2c_adapter **tuner_i2c_adapter)
|
||||||
{
|
{
|
||||||
struct i2c_client *client;
|
struct i2c_client *client;
|
||||||
struct i2c_board_info board_info;
|
struct i2c_board_info board_info;
|
||||||
struct m88ds3103_platform_data pdata;
|
struct m88ds3103_platform_data pdata = {};
|
||||||
|
|
||||||
pdata.clk = cfg->clock;
|
pdata.clk = cfg->clock;
|
||||||
pdata.i2c_wr_max = cfg->i2c_wr_max;
|
pdata.i2c_wr_max = cfg->i2c_wr_max;
|
||||||
|
@ -1409,6 +1410,8 @@ static int m88ds3103_probe(struct i2c_client *client,
|
||||||
case M88DS3103_CHIP_ID:
|
case M88DS3103_CHIP_ID:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
ret = -ENODEV;
|
||||||
|
dev_err(&client->dev, "Unknown device. Chip_id=%02x\n", dev->chip_id);
|
||||||
goto err_kfree;
|
goto err_kfree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -505,80 +505,77 @@ static struct i2c_vbi_ram_value vbi_ram_default[] =
|
||||||
/* FIXME: Current api doesn't handle all VBI types, those not
|
/* FIXME: Current api doesn't handle all VBI types, those not
|
||||||
yet supported are placed under #if 0 */
|
yet supported are placed under #if 0 */
|
||||||
#if 0
|
#if 0
|
||||||
{0x010, /* Teletext, SECAM, WST System A */
|
[0] = {0x010, /* Teletext, SECAM, WST System A */
|
||||||
{V4L2_SLICED_TELETEXT_SECAM,6,23,1},
|
{V4L2_SLICED_TELETEXT_SECAM,6,23,1},
|
||||||
{ 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x26,
|
{ 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x26,
|
||||||
0xe6, 0xb4, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00 }
|
0xe6, 0xb4, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00 }
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
{0x030, /* Teletext, PAL, WST System B */
|
[1] = {0x030, /* Teletext, PAL, WST System B */
|
||||||
{V4L2_SLICED_TELETEXT_B,6,22,1},
|
{V4L2_SLICED_TELETEXT_B,6,22,1},
|
||||||
{ 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x2b,
|
{ 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x2b,
|
||||||
0xa6, 0x72, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00 }
|
0xa6, 0x72, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00 }
|
||||||
},
|
},
|
||||||
#if 0
|
#if 0
|
||||||
{0x050, /* Teletext, PAL, WST System C */
|
[2] = {0x050, /* Teletext, PAL, WST System C */
|
||||||
{V4L2_SLICED_TELETEXT_PAL_C,6,22,1},
|
{V4L2_SLICED_TELETEXT_PAL_C,6,22,1},
|
||||||
{ 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22,
|
{ 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22,
|
||||||
0xa6, 0x98, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 }
|
0xa6, 0x98, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 }
|
||||||
},
|
},
|
||||||
{0x070, /* Teletext, NTSC, WST System B */
|
[3] = {0x070, /* Teletext, NTSC, WST System B */
|
||||||
{V4L2_SLICED_TELETEXT_NTSC_B,10,21,1},
|
{V4L2_SLICED_TELETEXT_NTSC_B,10,21,1},
|
||||||
{ 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x23,
|
{ 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x23,
|
||||||
0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 }
|
0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 }
|
||||||
},
|
},
|
||||||
{0x090, /* Tetetext, NTSC NABTS System C */
|
[4] = {0x090, /* Tetetext, NTSC NABTS System C */
|
||||||
{V4L2_SLICED_TELETEXT_NTSC_C,10,21,1},
|
{V4L2_SLICED_TELETEXT_NTSC_C,10,21,1},
|
||||||
{ 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22,
|
{ 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22,
|
||||||
0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x15, 0x00 }
|
0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x15, 0x00 }
|
||||||
},
|
},
|
||||||
{0x0b0, /* Teletext, NTSC-J, NABTS System D */
|
[5] = {0x0b0, /* Teletext, NTSC-J, NABTS System D */
|
||||||
{V4L2_SLICED_TELETEXT_NTSC_D,10,21,1},
|
{V4L2_SLICED_TELETEXT_NTSC_D,10,21,1},
|
||||||
{ 0xaa, 0xaa, 0xff, 0xff, 0xa7, 0x2e, 0x20, 0x23,
|
{ 0xaa, 0xaa, 0xff, 0xff, 0xa7, 0x2e, 0x20, 0x23,
|
||||||
0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 }
|
0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 }
|
||||||
},
|
},
|
||||||
{0x0d0, /* Closed Caption, PAL/SECAM */
|
[6] = {0x0d0, /* Closed Caption, PAL/SECAM */
|
||||||
{V4L2_SLICED_CAPTION_625,22,22,1},
|
{V4L2_SLICED_CAPTION_625,22,22,1},
|
||||||
{ 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02,
|
{ 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02,
|
||||||
0xa6, 0x7b, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 }
|
0xa6, 0x7b, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 }
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
{0x0f0, /* Closed Caption, NTSC */
|
[7] = {0x0f0, /* Closed Caption, NTSC */
|
||||||
{V4L2_SLICED_CAPTION_525,21,21,1},
|
{V4L2_SLICED_CAPTION_525,21,21,1},
|
||||||
{ 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02,
|
{ 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02,
|
||||||
0x69, 0x8c, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 }
|
0x69, 0x8c, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 }
|
||||||
},
|
},
|
||||||
{0x110, /* Wide Screen Signal, PAL/SECAM */
|
[8] = {0x110, /* Wide Screen Signal, PAL/SECAM */
|
||||||
{V4L2_SLICED_WSS_625,23,23,1},
|
{V4L2_SLICED_WSS_625,23,23,1},
|
||||||
{ 0x5b, 0x55, 0xc5, 0xff, 0x00, 0x71, 0x6e, 0x42,
|
{ 0x5b, 0x55, 0xc5, 0xff, 0x00, 0x71, 0x6e, 0x42,
|
||||||
0xa6, 0xcd, 0x0f, 0x00, 0x00, 0x00, 0x3a, 0x00 }
|
0xa6, 0xcd, 0x0f, 0x00, 0x00, 0x00, 0x3a, 0x00 }
|
||||||
},
|
},
|
||||||
#if 0
|
#if 0
|
||||||
{0x130, /* Wide Screen Signal, NTSC C */
|
[9] = {0x130, /* Wide Screen Signal, NTSC C */
|
||||||
{V4L2_SLICED_WSS_525,20,20,1},
|
{V4L2_SLICED_WSS_525,20,20,1},
|
||||||
{ 0x38, 0x00, 0x3f, 0x00, 0x00, 0x71, 0x6e, 0x43,
|
{ 0x38, 0x00, 0x3f, 0x00, 0x00, 0x71, 0x6e, 0x43,
|
||||||
0x69, 0x7c, 0x08, 0x00, 0x00, 0x00, 0x39, 0x00 }
|
0x69, 0x7c, 0x08, 0x00, 0x00, 0x00, 0x39, 0x00 }
|
||||||
},
|
},
|
||||||
{0x150, /* Vertical Interval Timecode (VITC), PAL/SECAM */
|
[10] = {0x150, /* Vertical Interval Timecode (VITC), PAL/SECAM */
|
||||||
{V4l2_SLICED_VITC_625,6,22,0},
|
{V4l2_SLICED_VITC_625,6,22,0},
|
||||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49,
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49,
|
||||||
0xa6, 0x85, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 }
|
0xa6, 0x85, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 }
|
||||||
},
|
},
|
||||||
{0x170, /* Vertical Interval Timecode (VITC), NTSC */
|
[11] = {0x170, /* Vertical Interval Timecode (VITC), NTSC */
|
||||||
{V4l2_SLICED_VITC_525,10,20,0},
|
{V4l2_SLICED_VITC_525,10,20,0},
|
||||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49,
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49,
|
||||||
0x69, 0x94, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 }
|
0x69, 0x94, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 }
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
{0x190, /* Video Program System (VPS), PAL */
|
[12] = {0x190, /* Video Program System (VPS), PAL */
|
||||||
{V4L2_SLICED_VPS,16,16,0},
|
{V4L2_SLICED_VPS,16,16,0},
|
||||||
{ 0xaa, 0xaa, 0xff, 0xff, 0xba, 0xce, 0x2b, 0x0d,
|
{ 0xaa, 0xaa, 0xff, 0xff, 0xba, 0xce, 0x2b, 0x0d,
|
||||||
0xa6, 0xda, 0x0b, 0x00, 0x00, 0x00, 0x60, 0x00 }
|
0xa6, 0xda, 0x0b, 0x00, 0x00, 0x00, 0x60, 0x00 }
|
||||||
},
|
},
|
||||||
/* 0x1d0 User programmable */
|
/* 0x1d0 User programmable */
|
||||||
|
|
||||||
/* End of struct */
|
|
||||||
{ (u16)-1 }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int tvp5150_write_inittab(struct v4l2_subdev *sd,
|
static int tvp5150_write_inittab(struct v4l2_subdev *sd,
|
||||||
|
@ -591,10 +588,10 @@ static int tvp5150_write_inittab(struct v4l2_subdev *sd,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tvp5150_vdp_init(struct v4l2_subdev *sd,
|
static int tvp5150_vdp_init(struct v4l2_subdev *sd)
|
||||||
const struct i2c_vbi_ram_value *regs)
|
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
int j;
|
||||||
|
|
||||||
/* Disable Full Field */
|
/* Disable Full Field */
|
||||||
tvp5150_write(sd, TVP5150_FULL_FIELD_ENA, 0);
|
tvp5150_write(sd, TVP5150_FULL_FIELD_ENA, 0);
|
||||||
|
@ -604,14 +601,17 @@ static int tvp5150_vdp_init(struct v4l2_subdev *sd,
|
||||||
tvp5150_write(sd, i, 0xff);
|
tvp5150_write(sd, i, 0xff);
|
||||||
|
|
||||||
/* Load Ram Table */
|
/* Load Ram Table */
|
||||||
while (regs->reg != (u16)-1) {
|
for (j = 0; j < ARRAY_SIZE(vbi_ram_default); j++) {
|
||||||
|
const struct i2c_vbi_ram_value *regs = &vbi_ram_default[j];
|
||||||
|
|
||||||
|
if (!regs->type.vbi_type)
|
||||||
|
continue;
|
||||||
|
|
||||||
tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_HIGH, regs->reg >> 8);
|
tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_HIGH, regs->reg >> 8);
|
||||||
tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_LOW, regs->reg);
|
tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_LOW, regs->reg);
|
||||||
|
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
tvp5150_write(sd, TVP5150_VDP_CONF_RAM_DATA, regs->values[i]);
|
tvp5150_write(sd, TVP5150_VDP_CONF_RAM_DATA, regs->values[i]);
|
||||||
|
|
||||||
regs++;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -620,19 +620,23 @@ static int tvp5150_vdp_init(struct v4l2_subdev *sd,
|
||||||
static int tvp5150_g_sliced_vbi_cap(struct v4l2_subdev *sd,
|
static int tvp5150_g_sliced_vbi_cap(struct v4l2_subdev *sd,
|
||||||
struct v4l2_sliced_vbi_cap *cap)
|
struct v4l2_sliced_vbi_cap *cap)
|
||||||
{
|
{
|
||||||
const struct i2c_vbi_ram_value *regs = vbi_ram_default;
|
int line, i;
|
||||||
int line;
|
|
||||||
|
|
||||||
dev_dbg_lvl(sd->dev, 1, debug, "g_sliced_vbi_cap\n");
|
dev_dbg_lvl(sd->dev, 1, debug, "g_sliced_vbi_cap\n");
|
||||||
memset(cap, 0, sizeof *cap);
|
memset(cap, 0, sizeof *cap);
|
||||||
|
|
||||||
while (regs->reg != (u16)-1 ) {
|
for (i = 0; i < ARRAY_SIZE(vbi_ram_default); i++) {
|
||||||
for (line=regs->type.ini_line;line<=regs->type.end_line;line++) {
|
const struct i2c_vbi_ram_value *regs = &vbi_ram_default[i];
|
||||||
|
|
||||||
|
if (!regs->type.vbi_type)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (line = regs->type.ini_line;
|
||||||
|
line <= regs->type.end_line;
|
||||||
|
line++) {
|
||||||
cap->service_lines[0][line] |= regs->type.vbi_type;
|
cap->service_lines[0][line] |= regs->type.vbi_type;
|
||||||
}
|
}
|
||||||
cap->service_set |= regs->type.vbi_type;
|
cap->service_set |= regs->type.vbi_type;
|
||||||
|
|
||||||
regs++;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -651,14 +655,13 @@ static int tvp5150_g_sliced_vbi_cap(struct v4l2_subdev *sd,
|
||||||
* MSB = field2
|
* MSB = field2
|
||||||
*/
|
*/
|
||||||
static int tvp5150_set_vbi(struct v4l2_subdev *sd,
|
static int tvp5150_set_vbi(struct v4l2_subdev *sd,
|
||||||
const struct i2c_vbi_ram_value *regs,
|
|
||||||
unsigned int type,u8 flags, int line,
|
unsigned int type,u8 flags, int line,
|
||||||
const int fields)
|
const int fields)
|
||||||
{
|
{
|
||||||
struct tvp5150 *decoder = to_tvp5150(sd);
|
struct tvp5150 *decoder = to_tvp5150(sd);
|
||||||
v4l2_std_id std = decoder->norm;
|
v4l2_std_id std = decoder->norm;
|
||||||
u8 reg;
|
u8 reg;
|
||||||
int pos = 0;
|
int i, pos = 0;
|
||||||
|
|
||||||
if (std == V4L2_STD_ALL) {
|
if (std == V4L2_STD_ALL) {
|
||||||
dev_err(sd->dev, "VBI can't be configured without knowing number of lines\n");
|
dev_err(sd->dev, "VBI can't be configured without knowing number of lines\n");
|
||||||
|
@ -671,19 +674,19 @@ static int tvp5150_set_vbi(struct v4l2_subdev *sd,
|
||||||
if (line < 6 || line > 27)
|
if (line < 6 || line > 27)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
while (regs->reg != (u16)-1) {
|
for (i = 0; i < ARRAY_SIZE(vbi_ram_default); i++) {
|
||||||
|
const struct i2c_vbi_ram_value *regs = &vbi_ram_default[i];
|
||||||
|
|
||||||
|
if (!regs->type.vbi_type)
|
||||||
|
continue;
|
||||||
|
|
||||||
if ((type & regs->type.vbi_type) &&
|
if ((type & regs->type.vbi_type) &&
|
||||||
(line >= regs->type.ini_line) &&
|
(line >= regs->type.ini_line) &&
|
||||||
(line <= regs->type.end_line))
|
(line <= regs->type.end_line))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
regs++;
|
|
||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regs->reg == (u16)-1)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
type = pos | (flags & 0xf0);
|
type = pos | (flags & 0xf0);
|
||||||
reg = ((line - 6) << 1) + TVP5150_LINE_MODE_INI;
|
reg = ((line - 6) << 1) + TVP5150_LINE_MODE_INI;
|
||||||
|
|
||||||
|
@ -696,8 +699,7 @@ static int tvp5150_set_vbi(struct v4l2_subdev *sd,
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tvp5150_get_vbi(struct v4l2_subdev *sd,
|
static int tvp5150_get_vbi(struct v4l2_subdev *sd, int line)
|
||||||
const struct i2c_vbi_ram_value *regs, int line)
|
|
||||||
{
|
{
|
||||||
struct tvp5150 *decoder = to_tvp5150(sd);
|
struct tvp5150 *decoder = to_tvp5150(sd);
|
||||||
v4l2_std_id std = decoder->norm;
|
v4l2_std_id std = decoder->norm;
|
||||||
|
@ -726,8 +728,8 @@ static int tvp5150_get_vbi(struct v4l2_subdev *sd,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
pos = ret & 0x0f;
|
pos = ret & 0x0f;
|
||||||
if (pos < 0x0f)
|
if (pos < ARRAY_SIZE(vbi_ram_default))
|
||||||
type |= regs[pos].type.vbi_type;
|
type |= vbi_ram_default[pos].type.vbi_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
|
@ -788,7 +790,7 @@ static int tvp5150_reset(struct v4l2_subdev *sd, u32 val)
|
||||||
tvp5150_write_inittab(sd, tvp5150_init_default);
|
tvp5150_write_inittab(sd, tvp5150_init_default);
|
||||||
|
|
||||||
/* Initializes VDP registers */
|
/* Initializes VDP registers */
|
||||||
tvp5150_vdp_init(sd, vbi_ram_default);
|
tvp5150_vdp_init(sd);
|
||||||
|
|
||||||
/* Selects decoder input */
|
/* Selects decoder input */
|
||||||
tvp5150_selmux(sd);
|
tvp5150_selmux(sd);
|
||||||
|
@ -1121,8 +1123,8 @@ static int tvp5150_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f
|
||||||
for (i = 0; i <= 23; i++) {
|
for (i = 0; i <= 23; i++) {
|
||||||
svbi->service_lines[1][i] = 0;
|
svbi->service_lines[1][i] = 0;
|
||||||
svbi->service_lines[0][i] =
|
svbi->service_lines[0][i] =
|
||||||
tvp5150_set_vbi(sd, vbi_ram_default,
|
tvp5150_set_vbi(sd, svbi->service_lines[0][i],
|
||||||
svbi->service_lines[0][i], 0xf0, i, 3);
|
0xf0, i, 3);
|
||||||
}
|
}
|
||||||
/* Enables FIFO */
|
/* Enables FIFO */
|
||||||
tvp5150_write(sd, TVP5150_FIFO_OUT_CTRL, 1);
|
tvp5150_write(sd, TVP5150_FIFO_OUT_CTRL, 1);
|
||||||
|
@ -1148,7 +1150,7 @@ static int tvp5150_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f
|
||||||
|
|
||||||
for (i = 0; i <= 23; i++) {
|
for (i = 0; i <= 23; i++) {
|
||||||
svbi->service_lines[0][i] =
|
svbi->service_lines[0][i] =
|
||||||
tvp5150_get_vbi(sd, vbi_ram_default, i);
|
tvp5150_get_vbi(sd, i);
|
||||||
mask |= svbi->service_lines[0][i];
|
mask |= svbi->service_lines[0][i];
|
||||||
}
|
}
|
||||||
svbi->service_set = mask;
|
svbi->service_set = mask;
|
||||||
|
|
|
@ -324,14 +324,15 @@ static int DvbDmxFilterCallback(u8 *buffer1, size_t buffer1_len,
|
||||||
}
|
}
|
||||||
return dvbdmxfilter->feed->cb.sec(buffer1, buffer1_len,
|
return dvbdmxfilter->feed->cb.sec(buffer1, buffer1_len,
|
||||||
buffer2, buffer2_len,
|
buffer2, buffer2_len,
|
||||||
&dvbdmxfilter->filter);
|
&dvbdmxfilter->filter, NULL);
|
||||||
case DMX_TYPE_TS:
|
case DMX_TYPE_TS:
|
||||||
if (!(dvbdmxfilter->feed->ts_type & TS_PACKET))
|
if (!(dvbdmxfilter->feed->ts_type & TS_PACKET))
|
||||||
return 0;
|
return 0;
|
||||||
if (dvbdmxfilter->feed->ts_type & TS_PAYLOAD_ONLY)
|
if (dvbdmxfilter->feed->ts_type & TS_PAYLOAD_ONLY)
|
||||||
return dvbdmxfilter->feed->cb.ts(buffer1, buffer1_len,
|
return dvbdmxfilter->feed->cb.ts(buffer1, buffer1_len,
|
||||||
buffer2, buffer2_len,
|
buffer2, buffer2_len,
|
||||||
&dvbdmxfilter->feed->feed.ts);
|
&dvbdmxfilter->feed->feed.ts,
|
||||||
|
NULL);
|
||||||
else
|
else
|
||||||
av7110_p2t_write(buffer1, buffer1_len,
|
av7110_p2t_write(buffer1, buffer1_len,
|
||||||
dvbdmxfilter->feed->pid,
|
dvbdmxfilter->feed->pid,
|
||||||
|
|
|
@ -99,7 +99,7 @@ int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len)
|
||||||
buf[4] = buf[5] = 0;
|
buf[4] = buf[5] = 0;
|
||||||
if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)
|
if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)
|
||||||
return dvbdmxfeed->cb.ts(buf, len, NULL, 0,
|
return dvbdmxfeed->cb.ts(buf, len, NULL, 0,
|
||||||
&dvbdmxfeed->feed.ts);
|
&dvbdmxfeed->feed.ts, NULL);
|
||||||
else
|
else
|
||||||
return dvb_filter_pes2ts(p2t, buf, len, 1);
|
return dvb_filter_pes2ts(p2t, buf, len, 1);
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ static int dvb_filter_pes2ts_cb(void *priv, unsigned char *data)
|
||||||
struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) priv;
|
struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) priv;
|
||||||
|
|
||||||
dvbdmxfeed->cb.ts(data, 188, NULL, 0,
|
dvbdmxfeed->cb.ts(data, 188, NULL, 0,
|
||||||
&dvbdmxfeed->feed.ts);
|
&dvbdmxfeed->feed.ts, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -814,7 +814,7 @@ static void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter,
|
||||||
memcpy(obuf + l, buf + c, TS_SIZE - l);
|
memcpy(obuf + l, buf + c, TS_SIZE - l);
|
||||||
c = length;
|
c = length;
|
||||||
}
|
}
|
||||||
feed->cb.ts(obuf, 188, NULL, 0, &feed->feed.ts);
|
feed->cb.ts(obuf, 188, NULL, 0, &feed->feed.ts, NULL);
|
||||||
pes_start = 0;
|
pes_start = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
config VIDEO_AU0828
|
config VIDEO_AU0828
|
||||||
tristate "Auvitek AU0828 support"
|
tristate "Auvitek AU0828 support"
|
||||||
depends on I2C && INPUT && DVB_CORE && USB
|
depends on I2C && INPUT && DVB_CORE && USB && VIDEO_V4L2
|
||||||
select I2C_ALGOBIT
|
select I2C_ALGOBIT
|
||||||
select VIDEO_TVEEPROM
|
select VIDEO_TVEEPROM
|
||||||
select VIDEOBUF2_VMALLOC
|
select VIDEOBUF2_VMALLOC
|
||||||
|
|
|
@ -428,7 +428,7 @@ static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data)
|
||||||
struct ttusb_dec *dec = priv;
|
struct ttusb_dec *dec = priv;
|
||||||
|
|
||||||
dec->audio_filter->feed->cb.ts(data, 188, NULL, 0,
|
dec->audio_filter->feed->cb.ts(data, 188, NULL, 0,
|
||||||
&dec->audio_filter->feed->feed.ts);
|
&dec->audio_filter->feed->feed.ts, NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -438,7 +438,7 @@ static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data)
|
||||||
struct ttusb_dec *dec = priv;
|
struct ttusb_dec *dec = priv;
|
||||||
|
|
||||||
dec->video_filter->feed->cb.ts(data, 188, NULL, 0,
|
dec->video_filter->feed->cb.ts(data, 188, NULL, 0,
|
||||||
&dec->video_filter->feed->feed.ts);
|
&dec->video_filter->feed->feed.ts, NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -490,7 +490,7 @@ static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length)
|
||||||
|
|
||||||
if (output_pva) {
|
if (output_pva) {
|
||||||
dec->video_filter->feed->cb.ts(pva, length, NULL, 0,
|
dec->video_filter->feed->cb.ts(pva, length, NULL, 0,
|
||||||
&dec->video_filter->feed->feed.ts);
|
&dec->video_filter->feed->feed.ts, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,7 +551,7 @@ static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length)
|
||||||
case 0x02: /* MainAudioStream */
|
case 0x02: /* MainAudioStream */
|
||||||
if (output_pva) {
|
if (output_pva) {
|
||||||
dec->audio_filter->feed->cb.ts(pva, length, NULL, 0,
|
dec->audio_filter->feed->cb.ts(pva, length, NULL, 0,
|
||||||
&dec->audio_filter->feed->feed.ts);
|
&dec->audio_filter->feed->feed.ts, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -589,7 +589,7 @@ static void ttusb_dec_process_filter(struct ttusb_dec *dec, u8 *packet,
|
||||||
|
|
||||||
if (filter)
|
if (filter)
|
||||||
filter->feed->cb.sec(&packet[2], length - 2, NULL, 0,
|
filter->feed->cb.sec(&packet[2], length - 2, NULL, 0,
|
||||||
&filter->filter);
|
&filter->filter, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ttusb_dec_process_packet(struct ttusb_dec *dec)
|
static void ttusb_dec_process_packet(struct ttusb_dec *dec)
|
||||||
|
|
|
@ -7,6 +7,7 @@ config VIDEO_V4L2
|
||||||
tristate
|
tristate
|
||||||
depends on (I2C || I2C=n) && VIDEO_DEV
|
depends on (I2C || I2C=n) && VIDEO_DEV
|
||||||
select RATIONAL
|
select RATIONAL
|
||||||
|
select VIDEOBUF2_V4L2 if VIDEOBUF2_CORE
|
||||||
default (I2C || I2C=n) && VIDEO_DEV
|
default (I2C || I2C=n) && VIDEO_DEV
|
||||||
|
|
||||||
config VIDEO_ADV_DEBUG
|
config VIDEO_ADV_DEBUG
|
||||||
|
|
|
@ -13,7 +13,7 @@ ifeq ($(CONFIG_COMPAT),y)
|
||||||
endif
|
endif
|
||||||
obj-$(CONFIG_V4L2_FWNODE) += v4l2-fwnode.o
|
obj-$(CONFIG_V4L2_FWNODE) += v4l2-fwnode.o
|
||||||
ifeq ($(CONFIG_TRACEPOINTS),y)
|
ifeq ($(CONFIG_TRACEPOINTS),y)
|
||||||
videodev-objs += vb2-trace.o v4l2-trace.o
|
videodev-objs += v4l2-trace.o
|
||||||
endif
|
endif
|
||||||
videodev-$(CONFIG_MEDIA_CONTROLLER) += v4l2-mc.o
|
videodev-$(CONFIG_MEDIA_CONTROLLER) += v4l2-mc.o
|
||||||
|
|
||||||
|
@ -35,4 +35,3 @@ obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o
|
||||||
|
|
||||||
ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
|
ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
|
||||||
ccflags-y += -I$(srctree)/drivers/media/tuners
|
ccflags-y += -I$(srctree)/drivers/media/tuners
|
||||||
|
|
||||||
|
|
|
@ -117,7 +117,7 @@ struct dmx_ts_feed {
|
||||||
* specified by @filter_value that will be used on the filter
|
* specified by @filter_value that will be used on the filter
|
||||||
* match logic.
|
* match logic.
|
||||||
* @filter_mode: Contains a 16 bytes (128 bits) filter mode.
|
* @filter_mode: Contains a 16 bytes (128 bits) filter mode.
|
||||||
* @parent: Pointer to struct dmx_section_feed.
|
* @parent: Back-pointer to struct dmx_section_feed.
|
||||||
* @priv: Pointer to private data of the API client.
|
* @priv: Pointer to private data of the API client.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
@ -130,8 +130,9 @@ struct dmx_section_filter {
|
||||||
u8 filter_value[DMX_MAX_FILTER_SIZE];
|
u8 filter_value[DMX_MAX_FILTER_SIZE];
|
||||||
u8 filter_mask[DMX_MAX_FILTER_SIZE];
|
u8 filter_mask[DMX_MAX_FILTER_SIZE];
|
||||||
u8 filter_mode[DMX_MAX_FILTER_SIZE];
|
u8 filter_mode[DMX_MAX_FILTER_SIZE];
|
||||||
struct dmx_section_feed *parent; /* Back-pointer */
|
struct dmx_section_feed *parent;
|
||||||
void *priv; /* Pointer to private data of the API client */
|
|
||||||
|
void *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -193,6 +194,10 @@ struct dmx_section_feed {
|
||||||
* @buffer2: Pointer to the tail of the filtered TS packets, or NULL.
|
* @buffer2: Pointer to the tail of the filtered TS packets, or NULL.
|
||||||
* @buffer2_length: Length of the TS data in buffer2.
|
* @buffer2_length: Length of the TS data in buffer2.
|
||||||
* @source: Indicates which TS feed is the source of the callback.
|
* @source: Indicates which TS feed is the source of the callback.
|
||||||
|
* @buffer_flags: Address where buffer flags are stored. Those are
|
||||||
|
* used to report discontinuity users via DVB
|
||||||
|
* memory mapped API, as defined by
|
||||||
|
* &enum dmx_buffer_flags.
|
||||||
*
|
*
|
||||||
* This function callback prototype, provided by the client of the demux API,
|
* This function callback prototype, provided by the client of the demux API,
|
||||||
* is called from the demux code. The function is only called when filtering
|
* is called from the demux code. The function is only called when filtering
|
||||||
|
@ -245,7 +250,8 @@ typedef int (*dmx_ts_cb)(const u8 *buffer1,
|
||||||
size_t buffer1_length,
|
size_t buffer1_length,
|
||||||
const u8 *buffer2,
|
const u8 *buffer2,
|
||||||
size_t buffer2_length,
|
size_t buffer2_length,
|
||||||
struct dmx_ts_feed *source);
|
struct dmx_ts_feed *source,
|
||||||
|
u32 *buffer_flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* typedef dmx_section_cb - DVB demux TS filter callback function prototype
|
* typedef dmx_section_cb - DVB demux TS filter callback function prototype
|
||||||
|
@ -261,6 +267,10 @@ typedef int (*dmx_ts_cb)(const u8 *buffer1,
|
||||||
* including headers and CRC.
|
* including headers and CRC.
|
||||||
* @source: Indicates which section feed is the source of the
|
* @source: Indicates which section feed is the source of the
|
||||||
* callback.
|
* callback.
|
||||||
|
* @buffer_flags: Address where buffer flags are stored. Those are
|
||||||
|
* used to report discontinuity users via DVB
|
||||||
|
* memory mapped API, as defined by
|
||||||
|
* &enum dmx_buffer_flags.
|
||||||
*
|
*
|
||||||
* This function callback prototype, provided by the client of the demux API,
|
* This function callback prototype, provided by the client of the demux API,
|
||||||
* is called from the demux code. The function is only called when
|
* is called from the demux code. The function is only called when
|
||||||
|
@ -286,7 +296,8 @@ typedef int (*dmx_section_cb)(const u8 *buffer1,
|
||||||
size_t buffer1_len,
|
size_t buffer1_len,
|
||||||
const u8 *buffer2,
|
const u8 *buffer2,
|
||||||
size_t buffer2_len,
|
size_t buffer2_len,
|
||||||
struct dmx_section_filter *source);
|
struct dmx_section_filter *source,
|
||||||
|
u32 *buffer_flags);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DVB Front-End
|
* DVB Front-End
|
||||||
|
|
|
@ -163,6 +163,7 @@ struct dmxdev_filter {
|
||||||
* @demux: pointer to &struct dmx_demux.
|
* @demux: pointer to &struct dmx_demux.
|
||||||
* @filternum: number of filters.
|
* @filternum: number of filters.
|
||||||
* @capabilities: demux capabilities as defined by &enum dmx_demux_caps.
|
* @capabilities: demux capabilities as defined by &enum dmx_demux_caps.
|
||||||
|
* @may_do_mmap: flag used to indicate if the device may do mmap.
|
||||||
* @exit: flag to indicate that the demux is being released.
|
* @exit: flag to indicate that the demux is being released.
|
||||||
* @dvr_orig_fe: pointer to &struct dmx_frontend.
|
* @dvr_orig_fe: pointer to &struct dmx_frontend.
|
||||||
* @dvr_buffer: embedded &struct dvb_ringbuffer for DVB output.
|
* @dvr_buffer: embedded &struct dvb_ringbuffer for DVB output.
|
||||||
|
@ -180,6 +181,7 @@ struct dmxdev {
|
||||||
int filternum;
|
int filternum;
|
||||||
int capabilities;
|
int capabilities;
|
||||||
|
|
||||||
|
unsigned int may_do_mmap:1;
|
||||||
unsigned int exit:1;
|
unsigned int exit:1;
|
||||||
#define DMXDEV_CAP_DUPLEX 1
|
#define DMXDEV_CAP_DUPLEX 1
|
||||||
struct dmx_frontend *dvr_orig_fe;
|
struct dmx_frontend *dvr_orig_fe;
|
||||||
|
|
|
@ -115,6 +115,8 @@ struct dvb_demux_filter {
|
||||||
* @pid: PID to be filtered.
|
* @pid: PID to be filtered.
|
||||||
* @timeout: feed timeout.
|
* @timeout: feed timeout.
|
||||||
* @filter: pointer to &struct dvb_demux_filter.
|
* @filter: pointer to &struct dvb_demux_filter.
|
||||||
|
* @buffer_flags: Buffer flags used to report discontinuity users via DVB
|
||||||
|
* memory mapped API, as defined by &enum dmx_buffer_flags.
|
||||||
* @ts_type: type of TS, as defined by &enum ts_filter_type.
|
* @ts_type: type of TS, as defined by &enum ts_filter_type.
|
||||||
* @pes_type: type of PES, as defined by &enum dmx_ts_pes.
|
* @pes_type: type of PES, as defined by &enum dmx_ts_pes.
|
||||||
* @cc: MPEG-TS packet continuity counter
|
* @cc: MPEG-TS packet continuity counter
|
||||||
|
@ -145,6 +147,8 @@ struct dvb_demux_feed {
|
||||||
ktime_t timeout;
|
ktime_t timeout;
|
||||||
struct dvb_demux_filter *filter;
|
struct dvb_demux_filter *filter;
|
||||||
|
|
||||||
|
u32 buffer_flags;
|
||||||
|
|
||||||
enum ts_filter_type ts_type;
|
enum ts_filter_type ts_type;
|
||||||
enum dmx_ts_pes pes_type;
|
enum dmx_ts_pes pes_type;
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,12 @@ struct dvb_buffer {
|
||||||
* @nonblocking:
|
* @nonblocking:
|
||||||
* If different than zero, device is operating on non-blocking
|
* If different than zero, device is operating on non-blocking
|
||||||
* mode.
|
* mode.
|
||||||
|
* @flags: buffer flags as defined by &enum dmx_buffer_flags.
|
||||||
|
* Filled only at &DMX_DQBUF. &DMX_QBUF should zero this field.
|
||||||
|
* @count: monotonic counter for filled buffers. Helps to identify
|
||||||
|
* data stream loses. Filled only at &DMX_DQBUF. &DMX_QBUF should
|
||||||
|
* zero this field.
|
||||||
|
*
|
||||||
* @name: name of the device type. Currently, it can either be
|
* @name: name of the device type. Currently, it can either be
|
||||||
* "dvr" or "demux_filter".
|
* "dvr" or "demux_filter".
|
||||||
*/
|
*/
|
||||||
|
@ -100,10 +106,14 @@ struct dvb_vb2_ctx {
|
||||||
int buf_siz;
|
int buf_siz;
|
||||||
int buf_cnt;
|
int buf_cnt;
|
||||||
int nonblocking;
|
int nonblocking;
|
||||||
|
|
||||||
|
enum dmx_buffer_flags flags;
|
||||||
|
u32 count;
|
||||||
|
|
||||||
char name[DVB_VB2_NAME_MAX + 1];
|
char name[DVB_VB2_NAME_MAX + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef DVB_MMAP
|
#ifndef CONFIG_DVB_MMAP
|
||||||
static inline int dvb_vb2_init(struct dvb_vb2_ctx *ctx,
|
static inline int dvb_vb2_init(struct dvb_vb2_ctx *ctx,
|
||||||
const char *name, int non_blocking)
|
const char *name, int non_blocking)
|
||||||
{
|
{
|
||||||
|
@ -114,7 +124,7 @@ static inline int dvb_vb2_release(struct dvb_vb2_ctx *ctx)
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
#define dvb_vb2_is_streaming(ctx) (0)
|
#define dvb_vb2_is_streaming(ctx) (0)
|
||||||
#define dvb_vb2_fill_buffer(ctx, file, wait) (0)
|
#define dvb_vb2_fill_buffer(ctx, file, wait, flags) (0)
|
||||||
|
|
||||||
static inline __poll_t dvb_vb2_poll(struct dvb_vb2_ctx *ctx,
|
static inline __poll_t dvb_vb2_poll(struct dvb_vb2_ctx *ctx,
|
||||||
struct file *file,
|
struct file *file,
|
||||||
|
@ -153,9 +163,13 @@ int dvb_vb2_is_streaming(struct dvb_vb2_ctx *ctx);
|
||||||
* @ctx: control struct for VB2 handler
|
* @ctx: control struct for VB2 handler
|
||||||
* @src: place where the data is stored
|
* @src: place where the data is stored
|
||||||
* @len: number of bytes to be copied from @src
|
* @len: number of bytes to be copied from @src
|
||||||
|
* @buffer_flags:
|
||||||
|
* pointer to buffer flags as defined by &enum dmx_buffer_flags.
|
||||||
|
* can be NULL.
|
||||||
*/
|
*/
|
||||||
int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx,
|
int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx,
|
||||||
const unsigned char *src, int len);
|
const unsigned char *src, int len,
|
||||||
|
enum dmx_buffer_flags *buffer_flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dvb_vb2_poll - Wrapper to vb2_core_streamon() for Digital TV
|
* dvb_vb2_poll - Wrapper to vb2_core_streamon() for Digital TV
|
||||||
|
|
|
@ -211,6 +211,32 @@ struct dmx_stc {
|
||||||
__u64 stc;
|
__u64 stc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum dmx_buffer_flags - DMX memory-mapped buffer flags
|
||||||
|
*
|
||||||
|
* @DMX_BUFFER_FLAG_HAD_CRC32_DISCARD:
|
||||||
|
* Indicates that the Kernel discarded one or more frames due to wrong
|
||||||
|
* CRC32 checksum.
|
||||||
|
* @DMX_BUFFER_FLAG_TEI:
|
||||||
|
* Indicates that the Kernel has detected a Transport Error indicator
|
||||||
|
* (TEI) on a filtered pid.
|
||||||
|
* @DMX_BUFFER_PKT_COUNTER_MISMATCH:
|
||||||
|
* Indicates that the Kernel has detected a packet counter mismatch
|
||||||
|
* on a filtered pid.
|
||||||
|
* @DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED:
|
||||||
|
* Indicates that the Kernel has detected one or more frame discontinuity.
|
||||||
|
* @DMX_BUFFER_FLAG_DISCONTINUITY_INDICATOR:
|
||||||
|
* Received at least one packet with a frame discontinuity indicator.
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum dmx_buffer_flags {
|
||||||
|
DMX_BUFFER_FLAG_HAD_CRC32_DISCARD = 1 << 0,
|
||||||
|
DMX_BUFFER_FLAG_TEI = 1 << 1,
|
||||||
|
DMX_BUFFER_PKT_COUNTER_MISMATCH = 1 << 2,
|
||||||
|
DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED = 1 << 3,
|
||||||
|
DMX_BUFFER_FLAG_DISCONTINUITY_INDICATOR = 1 << 4,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct dmx_buffer - dmx buffer info
|
* struct dmx_buffer - dmx buffer info
|
||||||
*
|
*
|
||||||
|
@ -220,15 +246,24 @@ struct dmx_stc {
|
||||||
* offset from the start of the device memory for this plane,
|
* offset from the start of the device memory for this plane,
|
||||||
* (or a "cookie" that should be passed to mmap() as offset)
|
* (or a "cookie" that should be passed to mmap() as offset)
|
||||||
* @length: size in bytes of the buffer
|
* @length: size in bytes of the buffer
|
||||||
|
* @flags: bit array of buffer flags as defined by &enum dmx_buffer_flags.
|
||||||
|
* Filled only at &DMX_DQBUF.
|
||||||
|
* @count: monotonic counter for filled buffers. Helps to identify
|
||||||
|
* data stream loses. Filled only at &DMX_DQBUF.
|
||||||
*
|
*
|
||||||
* Contains data exchanged by application and driver using one of the streaming
|
* Contains data exchanged by application and driver using one of the streaming
|
||||||
* I/O methods.
|
* I/O methods.
|
||||||
|
*
|
||||||
|
* Please notice that, for &DMX_QBUF, only @index should be filled.
|
||||||
|
* On &DMX_DQBUF calls, all fields will be filled by the Kernel.
|
||||||
*/
|
*/
|
||||||
struct dmx_buffer {
|
struct dmx_buffer {
|
||||||
__u32 index;
|
__u32 index;
|
||||||
__u32 bytesused;
|
__u32 bytesused;
|
||||||
__u32 offset;
|
__u32 offset;
|
||||||
__u32 length;
|
__u32 length;
|
||||||
|
__u32 flags;
|
||||||
|
__u32 count;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue