Merge branch 'patchwork' into v4l_for_linus
* patchwork: (496 commits) [media] v4l: tvp5150: Add missing break in set control handler [media] v4l: tvp5150: Don't inline the tvp5150_selmux() function [media] v4l: tvp5150: Compile tvp5150_link_setup out if !CONFIG_MEDIA_CONTROLLER [media] em28xx: don't store usb_device at struct em28xx [media] em28xx: use usb_interface for dev_foo() calls [media] em28xx: don't change the device's name [media] mn88472: fix chip id check on probe [media] mn88473: fix chip id check on probe [media] lirc: fix error paths in lirc_cdev_add() [media] s5p-mfc: Add support for MFC v8 available in Exynos 5433 SoCs [media] s5p-mfc: Rework clock handling [media] s5p-mfc: Don't keep clock prepared all the time [media] s5p-mfc: Kill all IS_ERR_OR_NULL in clocks management code [media] s5p-mfc: Remove dead conditional code [media] s5p-mfc: Ensure that clock is disabled before turning power off [media] s5p-mfc: Remove special clock rate management [media] s5p-mfc: Use printk_ratelimited for reporting ioctl errors [media] s5p-mfc: Set DMA_ATTR_ALLOC_SINGLE_PAGES [media] vivid: Set color_enc on HSV formats [media] v4l2-tpg: Init hv_enc field with a valid value ...
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
config DVB_MAX_ADAPTERS
|
||||
int "maximum number of DVB/ATSC adapters"
|
||||
depends on DVB_CORE
|
||||
default 8
|
||||
default 16
|
||||
range 1 255
|
||||
help
|
||||
Maximum number of DVB/ATSC adapters. Increasing this number
|
||||
@@ -13,7 +13,7 @@ config DVB_MAX_ADAPTERS
|
||||
if a much lower number of DVB/ATSC adapters is present.
|
||||
Only values in the range 4-32 are tested.
|
||||
|
||||
If you are unsure about this, use the default value 8
|
||||
If you are unsure about this, use the default value 16
|
||||
|
||||
config DVB_DYNAMIC_MINORS
|
||||
bool "Dynamic DVB minor allocation"
|
||||
@@ -27,3 +27,16 @@ config DVB_DYNAMIC_MINORS
|
||||
will be required to manage the device nodes.
|
||||
|
||||
If you are unsure about this, say N here.
|
||||
|
||||
config DVB_DEMUX_SECTION_LOSS_LOG
|
||||
bool "Enable DVB demux section packet loss log"
|
||||
depends on DVB_CORE
|
||||
default n
|
||||
help
|
||||
Enable extra log messages meant to detect packet loss
|
||||
inside the Kernel.
|
||||
|
||||
Should not be enabled on normal cases, as logs can
|
||||
be very verbose.
|
||||
|
||||
If you are unsure about this, say N here.
|
||||
|
@@ -4,7 +4,7 @@
|
||||
|
||||
dvb-net-$(CONFIG_DVB_NET) := dvb_net.o
|
||||
|
||||
dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \
|
||||
dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o \
|
||||
dvb_ca_en50221.o dvb_frontend.o \
|
||||
$(dvb-net-y) dvb_ringbuffer.o dvb_math.o
|
||||
|
||||
|
@@ -103,7 +103,6 @@ struct dmx_ts_feed {
|
||||
u16 pid,
|
||||
int type,
|
||||
enum dmx_ts_pes pes_type,
|
||||
size_t circular_buffer_size,
|
||||
ktime_t timeout);
|
||||
int (*start_filtering)(struct dmx_ts_feed *feed);
|
||||
int (*stop_filtering)(struct dmx_ts_feed *feed);
|
||||
@@ -181,7 +180,6 @@ struct dmx_section_feed {
|
||||
/* public: */
|
||||
int (*set)(struct dmx_section_feed *feed,
|
||||
u16 pid,
|
||||
size_t circular_buffer_size,
|
||||
int check_crc);
|
||||
int (*allocate_filter)(struct dmx_section_feed *feed,
|
||||
struct dmx_section_filter **filter);
|
||||
@@ -206,8 +204,7 @@ struct dmx_section_feed {
|
||||
* the &dmx_demux.
|
||||
* Any TS packets that match the filter settings are copied to a circular
|
||||
* buffer. The filtered TS packets are delivered to the client using this
|
||||
* callback function. The size of the circular buffer is controlled by the
|
||||
* circular_buffer_size parameter of the &dmx_ts_feed.@set function.
|
||||
* callback function.
|
||||
* It is expected that the @buffer1 and @buffer2 callback parameters point to
|
||||
* addresses within the circular buffer, but other implementations are also
|
||||
* possible. Note that the called party should not try to free the memory
|
||||
|
@@ -20,6 +20,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "dmxdev: " fmt
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/slab.h>
|
||||
@@ -36,7 +38,11 @@ static int debug;
|
||||
module_param(debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
|
||||
|
||||
#define dprintk if (debug) printk
|
||||
#define dprintk(fmt, arg...) do { \
|
||||
if (debug) \
|
||||
printk(KERN_DEBUG pr_fmt("%s: " fmt), \
|
||||
__func__, ##arg); \
|
||||
} while (0)
|
||||
|
||||
static int dvb_dmxdev_buffer_write(struct dvb_ringbuffer *buf,
|
||||
const u8 *src, size_t len)
|
||||
@@ -50,7 +56,7 @@ static int dvb_dmxdev_buffer_write(struct dvb_ringbuffer *buf,
|
||||
|
||||
free = dvb_ringbuffer_free(buf);
|
||||
if (len > free) {
|
||||
dprintk("dmxdev: buffer overflow\n");
|
||||
dprintk("buffer overflow\n");
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
|
||||
@@ -126,7 +132,7 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
|
||||
struct dmxdev *dmxdev = dvbdev->priv;
|
||||
struct dmx_frontend *front;
|
||||
|
||||
dprintk("function : %s\n", __func__);
|
||||
dprintk("%s\n", __func__);
|
||||
|
||||
if (mutex_lock_interruptible(&dmxdev->mutex))
|
||||
return -ERESTARTSYS;
|
||||
@@ -258,7 +264,7 @@ static int dvb_dvr_set_buffer_size(struct dmxdev *dmxdev,
|
||||
void *newmem;
|
||||
void *oldmem;
|
||||
|
||||
dprintk("function : %s\n", __func__);
|
||||
dprintk("%s\n", __func__);
|
||||
|
||||
if (buf->size == size)
|
||||
return 0;
|
||||
@@ -367,7 +373,7 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
|
||||
return 0;
|
||||
}
|
||||
del_timer(&dmxdevfilter->timer);
|
||||
dprintk("dmxdev: section callback %*ph\n", 6, buffer1);
|
||||
dprintk("section callback %*ph\n", 6, buffer1);
|
||||
ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer1,
|
||||
buffer1_len);
|
||||
if (ret == buffer1_len) {
|
||||
@@ -589,7 +595,7 @@ static int dvb_dmxdev_start_feed(struct dmxdev *dmxdev,
|
||||
tsfeed = feed->ts;
|
||||
tsfeed->priv = filter;
|
||||
|
||||
ret = tsfeed->set(tsfeed, feed->pid, ts_type, ts_pes, 32768, timeout);
|
||||
ret = tsfeed->set(tsfeed, feed->pid, ts_type, ts_pes, timeout);
|
||||
if (ret < 0) {
|
||||
dmxdev->demux->release_ts_feed(dmxdev->demux, tsfeed);
|
||||
return ret;
|
||||
@@ -655,15 +661,15 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
|
||||
secfeed,
|
||||
dvb_dmxdev_section_callback);
|
||||
if (ret < 0) {
|
||||
printk("DVB (%s): could not alloc feed\n",
|
||||
pr_err("DVB (%s): could not alloc feed\n",
|
||||
__func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = (*secfeed)->set(*secfeed, para->pid, 32768,
|
||||
ret = (*secfeed)->set(*secfeed, para->pid,
|
||||
(para->flags & DMX_CHECK_CRC) ? 1 : 0);
|
||||
if (ret < 0) {
|
||||
printk("DVB (%s): could not set feed\n",
|
||||
pr_err("DVB (%s): could not set feed\n",
|
||||
__func__);
|
||||
dvb_dmxdev_feed_restart(filter);
|
||||
return ret;
|
||||
@@ -844,7 +850,7 @@ static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev,
|
||||
struct dmxdev_filter *dmxdevfilter,
|
||||
struct dmx_sct_filter_params *params)
|
||||
{
|
||||
dprintk("function : %s, PID=0x%04x, flags=%02x, timeout=%d\n",
|
||||
dprintk("%s: PID=0x%04x, flags=%02x, timeout=%d\n",
|
||||
__func__, params->pid, params->flags, params->timeout);
|
||||
|
||||
dvb_dmxdev_filter_stop(dmxdevfilter);
|
||||
@@ -1184,7 +1190,7 @@ static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait)
|
||||
struct dmxdev *dmxdev = dvbdev->priv;
|
||||
unsigned int mask = 0;
|
||||
|
||||
dprintk("function : %s\n", __func__);
|
||||
dprintk("%s\n", __func__);
|
||||
|
||||
if (dmxdev->exit)
|
||||
return POLLERR;
|
||||
|
@@ -262,6 +262,7 @@
|
||||
#define USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI 0x3012
|
||||
#define USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI_2 0x3015
|
||||
#define USB_PID_TECHNOTREND_TVSTICK_CT2_4400 0x3014
|
||||
#define USB_PID_TECHNOTREND_CONNECT_S2_4650_CI 0x3017
|
||||
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
|
||||
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081
|
||||
#define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058
|
||||
@@ -411,4 +412,5 @@
|
||||
#define USB_PID_SVEON_STV27 0xd3af
|
||||
#define USB_PID_TURBOX_DTT_2000 0xd3a4
|
||||
#define USB_PID_WINTV_SOLOHD 0x0264
|
||||
#define USB_PID_EVOLVEO_XTRATV_STICK 0xa115
|
||||
#endif
|
||||
|
@@ -28,6 +28,8 @@
|
||||
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "dvb_ca_en50221: " fmt
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/list.h>
|
||||
@@ -46,7 +48,10 @@ static int dvb_ca_en50221_debug;
|
||||
module_param_named(cam_debug, dvb_ca_en50221_debug, int, 0644);
|
||||
MODULE_PARM_DESC(cam_debug, "enable verbose debug messages");
|
||||
|
||||
#define dprintk if (dvb_ca_en50221_debug) printk
|
||||
#define dprintk(fmt, arg...) do { \
|
||||
if (dvb_ca_en50221_debug) \
|
||||
printk(KERN_DEBUG pr_fmt("%s: " fmt), __func__, ##arg);\
|
||||
} while (0)
|
||||
|
||||
#define INIT_TIMEOUT_SECS 10
|
||||
|
||||
@@ -166,7 +171,7 @@ static void dvb_ca_private_free(struct dvb_ca_private *ca)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
dvb_unregister_device(ca->dvbdev);
|
||||
dvb_free_device(ca->dvbdev);
|
||||
for (i = 0; i < ca->slot_count; i++)
|
||||
vfree(ca->slot_info[i].rx_buffer.data);
|
||||
|
||||
@@ -298,7 +303,8 @@ static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot,
|
||||
|
||||
/* if we got the flags, it was successful! */
|
||||
if (res & waitfor) {
|
||||
dprintk("%s succeeded timeout:%lu\n", __func__, jiffies - start);
|
||||
dprintk("%s succeeded timeout:%lu\n",
|
||||
__func__, jiffies - start);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -519,8 +525,9 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot)
|
||||
|
||||
/* is it a version we support? */
|
||||
if (strncmp(dvb_str + 8, "1.00", 4)) {
|
||||
printk("dvb_ca adapter %d: Unsupported DVB CAM module version %c%c%c%c\n",
|
||||
ca->dvbdev->adapter->num, dvb_str[8], dvb_str[9], dvb_str[10], dvb_str[11]);
|
||||
pr_err("dvb_ca adapter %d: Unsupported DVB CAM module version %c%c%c%c\n",
|
||||
ca->dvbdev->adapter->num, dvb_str[8], dvb_str[9],
|
||||
dvb_str[10], dvb_str[11]);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -557,8 +564,8 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot)
|
||||
break;
|
||||
|
||||
default: /* Unknown tuple type - just skip this tuple and move to the next one */
|
||||
dprintk("dvb_ca: Skipping unknown tuple type:0x%x length:0x%x\n", tupleType,
|
||||
tupleLength);
|
||||
dprintk("dvb_ca: Skipping unknown tuple type:0x%x length:0x%x\n",
|
||||
tupleType, tupleLength);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -567,7 +574,8 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot)
|
||||
return -EINVAL;
|
||||
|
||||
dprintk("Valid DVB CAM detected MANID:%x DEVID:%x CONFIGBASE:0x%x CONFIGOPTION:0x%x\n",
|
||||
manfid, devid, ca->slot_info[slot].config_base, ca->slot_info[slot].config_option);
|
||||
manfid, devid, ca->slot_info[slot].config_base,
|
||||
ca->slot_info[slot].config_option);
|
||||
|
||||
// success!
|
||||
return 0;
|
||||
@@ -661,14 +669,15 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, u8 * eb
|
||||
/* check it will fit */
|
||||
if (ebuf == NULL) {
|
||||
if (bytes_read > ca->slot_info[slot].link_buf_size) {
|
||||
printk("dvb_ca adapter %d: CAM tried to send a buffer larger than the link buffer size (%i > %i)!\n",
|
||||
ca->dvbdev->adapter->num, bytes_read, ca->slot_info[slot].link_buf_size);
|
||||
pr_err("dvb_ca adapter %d: CAM tried to send a buffer larger than the link buffer size (%i > %i)!\n",
|
||||
ca->dvbdev->adapter->num, bytes_read,
|
||||
ca->slot_info[slot].link_buf_size);
|
||||
ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
|
||||
status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
if (bytes_read < 2) {
|
||||
printk("dvb_ca adapter %d: CAM sent a buffer that was less than 2 bytes!\n",
|
||||
pr_err("dvb_ca adapter %d: CAM sent a buffer that was less than 2 bytes!\n",
|
||||
ca->dvbdev->adapter->num);
|
||||
ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
|
||||
status = -EIO;
|
||||
@@ -676,7 +685,7 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, u8 * eb
|
||||
}
|
||||
} else {
|
||||
if (bytes_read > ecount) {
|
||||
printk("dvb_ca adapter %d: CAM tried to send a buffer larger than the ecount size!\n",
|
||||
pr_err("dvb_ca adapter %d: CAM tried to send a buffer larger than the ecount size!\n",
|
||||
ca->dvbdev->adapter->num);
|
||||
status = -EIO;
|
||||
goto exit;
|
||||
@@ -1062,7 +1071,7 @@ static int dvb_ca_en50221_thread(void *data)
|
||||
|
||||
case DVB_CA_SLOTSTATE_WAITREADY:
|
||||
if (time_after(jiffies, ca->slot_info[slot].timeout)) {
|
||||
printk("dvb_ca adaptor %d: PC card did not respond :(\n",
|
||||
pr_err("dvb_ca adaptor %d: PC card did not respond :(\n",
|
||||
ca->dvbdev->adapter->num);
|
||||
ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
|
||||
dvb_ca_en50221_thread_update_delay(ca);
|
||||
@@ -1084,14 +1093,14 @@ static int dvb_ca_en50221_thread(void *data)
|
||||
}
|
||||
}
|
||||
|
||||
printk("dvb_ca adapter %d: Invalid PC card inserted :(\n",
|
||||
pr_err("dvb_ca adapter %d: Invalid PC card inserted :(\n",
|
||||
ca->dvbdev->adapter->num);
|
||||
ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
|
||||
dvb_ca_en50221_thread_update_delay(ca);
|
||||
break;
|
||||
}
|
||||
if (dvb_ca_en50221_set_configoption(ca, slot) != 0) {
|
||||
printk("dvb_ca adapter %d: Unable to initialise CAM :(\n",
|
||||
pr_err("dvb_ca adapter %d: Unable to initialise CAM :(\n",
|
||||
ca->dvbdev->adapter->num);
|
||||
ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
|
||||
dvb_ca_en50221_thread_update_delay(ca);
|
||||
@@ -1099,7 +1108,7 @@ static int dvb_ca_en50221_thread(void *data)
|
||||
}
|
||||
if (ca->pub->write_cam_control(ca->pub, slot,
|
||||
CTRLIF_COMMAND, CMDREG_RS) != 0) {
|
||||
printk("dvb_ca adapter %d: Unable to reset CAM IF\n",
|
||||
pr_err("dvb_ca adapter %d: Unable to reset CAM IF\n",
|
||||
ca->dvbdev->adapter->num);
|
||||
ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
|
||||
dvb_ca_en50221_thread_update_delay(ca);
|
||||
@@ -1114,7 +1123,7 @@ static int dvb_ca_en50221_thread(void *data)
|
||||
|
||||
case DVB_CA_SLOTSTATE_WAITFR:
|
||||
if (time_after(jiffies, ca->slot_info[slot].timeout)) {
|
||||
printk("dvb_ca adapter %d: DVB CAM did not respond :(\n",
|
||||
pr_err("dvb_ca adapter %d: DVB CAM did not respond :(\n",
|
||||
ca->dvbdev->adapter->num);
|
||||
ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
|
||||
dvb_ca_en50221_thread_update_delay(ca);
|
||||
@@ -1141,7 +1150,8 @@ static int dvb_ca_en50221_thread(void *data)
|
||||
}
|
||||
}
|
||||
|
||||
printk("dvb_ca adapter %d: DVB CAM link initialisation failed :(\n", ca->dvbdev->adapter->num);
|
||||
pr_err("dvb_ca adapter %d: DVB CAM link initialisation failed :(\n",
|
||||
ca->dvbdev->adapter->num);
|
||||
ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
|
||||
dvb_ca_en50221_thread_update_delay(ca);
|
||||
break;
|
||||
@@ -1150,7 +1160,8 @@ static int dvb_ca_en50221_thread(void *data)
|
||||
if (ca->slot_info[slot].rx_buffer.data == NULL) {
|
||||
rxbuf = vmalloc(RX_BUFFER_SIZE);
|
||||
if (rxbuf == NULL) {
|
||||
printk("dvb_ca adapter %d: Unable to allocate CAM rx buffer :(\n", ca->dvbdev->adapter->num);
|
||||
pr_err("dvb_ca adapter %d: Unable to allocate CAM rx buffer :(\n",
|
||||
ca->dvbdev->adapter->num);
|
||||
ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
|
||||
dvb_ca_en50221_thread_update_delay(ca);
|
||||
break;
|
||||
@@ -1161,7 +1172,8 @@ static int dvb_ca_en50221_thread(void *data)
|
||||
ca->pub->slot_ts_enable(ca->pub, slot);
|
||||
ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_RUNNING;
|
||||
dvb_ca_en50221_thread_update_delay(ca);
|
||||
printk("dvb_ca adapter %d: DVB CAM detected and initialised successfully\n", ca->dvbdev->adapter->num);
|
||||
pr_err("dvb_ca adapter %d: DVB CAM detected and initialised successfully\n",
|
||||
ca->dvbdev->adapter->num);
|
||||
break;
|
||||
|
||||
case DVB_CA_SLOTSTATE_RUNNING:
|
||||
@@ -1497,7 +1509,8 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf,
|
||||
pktlen = 2;
|
||||
do {
|
||||
if (idx == -1) {
|
||||
printk("dvb_ca adapter %d: BUG: read packet ended before last_fragment encountered\n", ca->dvbdev->adapter->num);
|
||||
pr_err("dvb_ca adapter %d: BUG: read packet ended before last_fragment encountered\n",
|
||||
ca->dvbdev->adapter->num);
|
||||
status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
@@ -1755,8 +1768,8 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
|
||||
ca->dvbdev->adapter->num, ca->dvbdev->id);
|
||||
if (IS_ERR(ca->thread)) {
|
||||
ret = PTR_ERR(ca->thread);
|
||||
printk("dvb_ca_init: failed to start kernel_thread (%d)\n",
|
||||
ret);
|
||||
pr_err("dvb_ca_init: failed to start kernel_thread (%d)\n",
|
||||
ret);
|
||||
goto unregister_device;
|
||||
}
|
||||
return 0;
|
||||
@@ -1794,6 +1807,7 @@ void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca)
|
||||
for (i = 0; i < ca->slot_count; i++) {
|
||||
dvb_ca_en50221_slot_shutdown(ca, i);
|
||||
}
|
||||
dvb_remove_device(ca->dvbdev);
|
||||
dvb_ca_private_put(ca);
|
||||
pubca->private = NULL;
|
||||
}
|
||||
|
@@ -21,6 +21,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "dvb_demux: " fmt
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/slab.h>
|
||||
@@ -34,12 +36,6 @@
|
||||
|
||||
#include "dvb_demux.h"
|
||||
|
||||
#define NOBUFS
|
||||
/*
|
||||
** #define DVB_DEMUX_SECTION_LOSS_LOG to monitor payload loss in the syslog
|
||||
*/
|
||||
// #define DVB_DEMUX_SECTION_LOSS_LOG
|
||||
|
||||
static int dvb_demux_tscheck;
|
||||
module_param(dvb_demux_tscheck, int, 0644);
|
||||
MODULE_PARM_DESC(dvb_demux_tscheck,
|
||||
@@ -55,10 +51,13 @@ module_param(dvb_demux_feed_err_pkts, int, 0644);
|
||||
MODULE_PARM_DESC(dvb_demux_feed_err_pkts,
|
||||
"when set to 0, drop packets with the TEI bit set (1 by default)");
|
||||
|
||||
#define dprintk_tscheck(x...) do { \
|
||||
if (dvb_demux_tscheck && printk_ratelimit()) \
|
||||
printk(x); \
|
||||
} while (0)
|
||||
#define dprintk(fmt, arg...) \
|
||||
printk(KERN_DEBUG pr_fmt("%s: " fmt), __func__, ##arg)
|
||||
|
||||
#define dprintk_tscheck(x...) do { \
|
||||
if (dvb_demux_tscheck && printk_ratelimit()) \
|
||||
dprintk(x); \
|
||||
} while (0)
|
||||
|
||||
/******************************************************************************
|
||||
* static inlined helper functions
|
||||
@@ -109,21 +108,23 @@ static inline int dvb_dmx_swfilter_payload(struct dvb_demux_feed *feed,
|
||||
{
|
||||
int count = payload(buf);
|
||||
int p;
|
||||
//int ccok;
|
||||
//u8 cc;
|
||||
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
|
||||
int ccok;
|
||||
u8 cc;
|
||||
#endif
|
||||
|
||||
if (count == 0)
|
||||
return -1;
|
||||
|
||||
p = 188 - count;
|
||||
|
||||
/*
|
||||
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
|
||||
cc = buf[3] & 0x0f;
|
||||
ccok = ((feed->cc + 1) & 0x0f) == cc;
|
||||
feed->cc = cc;
|
||||
if (!ccok)
|
||||
printk("missed packet!\n");
|
||||
*/
|
||||
dprintk("missed packet!\n");
|
||||
#endif
|
||||
|
||||
if (buf[1] & 0x40) // PUSI ?
|
||||
feed->peslen = 0xfffa;
|
||||
@@ -189,7 +190,7 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
|
||||
{
|
||||
struct dmx_section_feed *sec = &feed->feed.sec;
|
||||
|
||||
#ifdef DVB_DEMUX_SECTION_LOSS_LOG
|
||||
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
|
||||
if (sec->secbufp < sec->tsfeedp) {
|
||||
int i, n = sec->tsfeedp - sec->secbufp;
|
||||
|
||||
@@ -199,12 +200,12 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
|
||||
* but just first and last.
|
||||
*/
|
||||
if (sec->secbuf[0] != 0xff || sec->secbuf[n - 1] != 0xff) {
|
||||
printk("dvb_demux.c section ts padding loss: %d/%d\n",
|
||||
dprintk("dvb_demux.c section ts padding loss: %d/%d\n",
|
||||
n, sec->tsfeedp);
|
||||
printk("dvb_demux.c pad data:");
|
||||
dprintk("dvb_demux.c pad data:");
|
||||
for (i = 0; i < n; i++)
|
||||
printk(" %02x", sec->secbuf[i]);
|
||||
printk("\n");
|
||||
pr_cont(" %02x", sec->secbuf[i]);
|
||||
pr_cont("\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -242,8 +243,8 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
|
||||
return 0;
|
||||
|
||||
if (sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE) {
|
||||
#ifdef DVB_DEMUX_SECTION_LOSS_LOG
|
||||
printk("dvb_demux.c section buffer full loss: %d/%d\n",
|
||||
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
|
||||
dprintk("dvb_demux.c section buffer full loss: %d/%d\n",
|
||||
sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE,
|
||||
DMX_MAX_SECFEED_SIZE);
|
||||
#endif
|
||||
@@ -276,9 +277,9 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
|
||||
/* dump [secbuf .. secbuf+seclen) */
|
||||
if (feed->pusi_seen)
|
||||
dvb_dmx_swfilter_section_feed(feed);
|
||||
#ifdef DVB_DEMUX_SECTION_LOSS_LOG
|
||||
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
|
||||
else
|
||||
printk("dvb_demux.c pusi not seen, discarding section data\n");
|
||||
dprintk("dvb_demux.c pusi not seen, discarding section data\n");
|
||||
#endif
|
||||
sec->secbufp += seclen; /* secbufp and secbuf moving together is */
|
||||
sec->secbuf += seclen; /* redundant but saves pointer arithmetic */
|
||||
@@ -312,9 +313,9 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
|
||||
}
|
||||
|
||||
if (!ccok || dc_i) {
|
||||
#ifdef DVB_DEMUX_SECTION_LOSS_LOG
|
||||
printk("dvb_demux.c discontinuity detected %d bytes lost\n",
|
||||
count);
|
||||
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
|
||||
dprintk("dvb_demux.c discontinuity detected %d bytes lost\n",
|
||||
count);
|
||||
/*
|
||||
* those bytes under sume circumstances will again be reported
|
||||
* in the following dvb_dmx_swfilter_section_new
|
||||
@@ -344,9 +345,10 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
|
||||
dvb_dmx_swfilter_section_copy_dump(feed, after,
|
||||
after_len);
|
||||
}
|
||||
#ifdef DVB_DEMUX_SECTION_LOSS_LOG
|
||||
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
|
||||
else if (count > 0)
|
||||
printk("dvb_demux.c PUSI=1 but %d bytes lost\n", count);
|
||||
dprintk("dvb_demux.c PUSI=1 but %d bytes lost\n",
|
||||
count);
|
||||
#endif
|
||||
} else {
|
||||
/* PUSI=0 (is not set), no section boundary */
|
||||
@@ -415,9 +417,9 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
|
||||
1024);
|
||||
speed_timedelta = ktime_ms_delta(cur_time,
|
||||
demux->speed_last_time);
|
||||
printk(KERN_INFO "TS speed %llu Kbits/sec \n",
|
||||
div64_u64(speed_bytes,
|
||||
speed_timedelta));
|
||||
dprintk("TS speed %llu Kbits/sec \n",
|
||||
div64_u64(speed_bytes,
|
||||
speed_timedelta));
|
||||
}
|
||||
|
||||
demux->speed_last_time = cur_time;
|
||||
@@ -426,8 +428,7 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
|
||||
}
|
||||
|
||||
if (buf[1] & 0x80) {
|
||||
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]);
|
||||
/* data in this packet can't be trusted - drop it unless
|
||||
* module option dvb_demux_feed_err_pkts is set */
|
||||
@@ -635,7 +636,7 @@ static void dvb_demux_feed_add(struct dvb_demux_feed *feed)
|
||||
{
|
||||
spin_lock_irq(&feed->demux->lock);
|
||||
if (dvb_demux_feed_find(feed)) {
|
||||
printk(KERN_ERR "%s: feed already in list (type=%x state=%x pid=%x)\n",
|
||||
pr_err("%s: feed already in list (type=%x state=%x pid=%x)\n",
|
||||
__func__, feed->type, feed->state, feed->pid);
|
||||
goto out;
|
||||
}
|
||||
@@ -649,7 +650,7 @@ static void dvb_demux_feed_del(struct dvb_demux_feed *feed)
|
||||
{
|
||||
spin_lock_irq(&feed->demux->lock);
|
||||
if (!(dvb_demux_feed_find(feed))) {
|
||||
printk(KERN_ERR "%s: feed not in list (type=%x state=%x pid=%x)\n",
|
||||
pr_err("%s: feed not in list (type=%x state=%x pid=%x)\n",
|
||||
__func__, feed->type, feed->state, feed->pid);
|
||||
goto out;
|
||||
}
|
||||
@@ -660,8 +661,7 @@ out:
|
||||
}
|
||||
|
||||
static int dmx_ts_feed_set(struct dmx_ts_feed *ts_feed, u16 pid, int ts_type,
|
||||
enum dmx_ts_pes pes_type,
|
||||
size_t circular_buffer_size, ktime_t timeout)
|
||||
enum dmx_ts_pes pes_type, ktime_t timeout)
|
||||
{
|
||||
struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed;
|
||||
struct dvb_demux *demux = feed->demux;
|
||||
@@ -691,23 +691,10 @@ static int dmx_ts_feed_set(struct dmx_ts_feed *ts_feed, u16 pid, int ts_type,
|
||||
dvb_demux_feed_add(feed);
|
||||
|
||||
feed->pid = pid;
|
||||
feed->buffer_size = circular_buffer_size;
|
||||
feed->timeout = timeout;
|
||||
feed->ts_type = ts_type;
|
||||
feed->pes_type = pes_type;
|
||||
|
||||
if (feed->buffer_size) {
|
||||
#ifdef NOBUFS
|
||||
feed->buffer = NULL;
|
||||
#else
|
||||
feed->buffer = vmalloc(feed->buffer_size);
|
||||
if (!feed->buffer) {
|
||||
mutex_unlock(&demux->mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
feed->state = DMX_STATE_READY;
|
||||
mutex_unlock(&demux->mutex);
|
||||
|
||||
@@ -796,7 +783,6 @@ static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx,
|
||||
feed->demux = demux;
|
||||
feed->pid = 0xffff;
|
||||
feed->peslen = 0xfffa;
|
||||
feed->buffer = NULL;
|
||||
|
||||
(*ts_feed) = &feed->feed.ts;
|
||||
(*ts_feed)->parent = dmx;
|
||||
@@ -833,10 +819,6 @@ static int dvbdmx_release_ts_feed(struct dmx_demux *dmx,
|
||||
mutex_unlock(&demux->mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
#ifndef NOBUFS
|
||||
vfree(feed->buffer);
|
||||
feed->buffer = NULL;
|
||||
#endif
|
||||
|
||||
feed->state = DMX_STATE_FREE;
|
||||
feed->filter->state = DMX_STATE_FREE;
|
||||
@@ -888,8 +870,7 @@ static int dmx_section_feed_allocate_filter(struct dmx_section_feed *feed,
|
||||
}
|
||||
|
||||
static int dmx_section_feed_set(struct dmx_section_feed *feed,
|
||||
u16 pid, size_t circular_buffer_size,
|
||||
int check_crc)
|
||||
u16 pid, int check_crc)
|
||||
{
|
||||
struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
|
||||
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
|
||||
@@ -903,19 +884,8 @@ static int dmx_section_feed_set(struct dmx_section_feed *feed,
|
||||
dvb_demux_feed_add(dvbdmxfeed);
|
||||
|
||||
dvbdmxfeed->pid = pid;
|
||||
dvbdmxfeed->buffer_size = circular_buffer_size;
|
||||
dvbdmxfeed->feed.sec.check_crc = check_crc;
|
||||
|
||||
#ifdef NOBUFS
|
||||
dvbdmxfeed->buffer = NULL;
|
||||
#else
|
||||
dvbdmxfeed->buffer = vmalloc(dvbdmxfeed->buffer_size);
|
||||
if (!dvbdmxfeed->buffer) {
|
||||
mutex_unlock(&dvbdmx->mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
dvbdmxfeed->state = DMX_STATE_READY;
|
||||
mutex_unlock(&dvbdmx->mutex);
|
||||
return 0;
|
||||
@@ -1074,7 +1044,6 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux,
|
||||
dvbdmxfeed->feed.sec.secbufp = dvbdmxfeed->feed.sec.seclen = 0;
|
||||
dvbdmxfeed->feed.sec.tsfeedp = 0;
|
||||
dvbdmxfeed->filter = NULL;
|
||||
dvbdmxfeed->buffer = NULL;
|
||||
|
||||
(*feed) = &dvbdmxfeed->feed.sec;
|
||||
(*feed)->is_filtering = 0;
|
||||
@@ -1103,10 +1072,6 @@ static int dvbdmx_release_section_feed(struct dmx_demux *demux,
|
||||
mutex_unlock(&dvbdmx->mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
#ifndef NOBUFS
|
||||
vfree(dvbdmxfeed->buffer);
|
||||
dvbdmxfeed->buffer = NULL;
|
||||
#endif
|
||||
dvbdmxfeed->state = DMX_STATE_FREE;
|
||||
|
||||
dvb_demux_feed_del(dvbdmxfeed);
|
||||
@@ -1268,7 +1233,7 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux)
|
||||
|
||||
dvbdemux->cnt_storage = vmalloc(MAX_PID + 1);
|
||||
if (!dvbdemux->cnt_storage)
|
||||
printk(KERN_WARNING "Couldn't allocate memory for TS/TEI check. Disabling it\n");
|
||||
pr_warn("Couldn't allocate memory for TS/TEI check. Disabling it\n");
|
||||
|
||||
INIT_LIST_HEAD(&dvbdemux->frontend_list);
|
||||
|
||||
|
@@ -80,8 +80,6 @@ struct dvb_demux_feed {
|
||||
int type;
|
||||
int state;
|
||||
u16 pid;
|
||||
u8 *buffer;
|
||||
int buffer_size;
|
||||
|
||||
ktime_t timeout;
|
||||
struct dvb_demux_filter *filter;
|
||||
|
@@ -1,603 +0,0 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/string.h>
|
||||
#include "dvb_filter.h"
|
||||
|
||||
#if 0
|
||||
static unsigned int bitrates[3][16] =
|
||||
{{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0},
|
||||
{0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0},
|
||||
{0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}};
|
||||
#endif
|
||||
|
||||
static u32 freq[4] = {480, 441, 320, 0};
|
||||
|
||||
static unsigned int ac3_bitrates[32] =
|
||||
{32,40,48,56,64,80,96,112,128,160,192,224,256,320,384,448,512,576,640,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
|
||||
static u32 ac3_frames[3][32] =
|
||||
{{64,80,96,112,128,160,192,224,256,320,384,448,512,640,768,896,1024,
|
||||
1152,1280,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
{69,87,104,121,139,174,208,243,278,348,417,487,557,696,835,975,1114,
|
||||
1253,1393,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
{96,120,144,168,192,240,288,336,384,480,576,672,768,960,1152,1344,
|
||||
1536,1728,1920,0,0,0,0,0,0,0,0,0,0,0,0,0}};
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
static void setup_ts2pes(ipack *pa, ipack *pv, u16 *pida, u16 *pidv,
|
||||
void (*pes_write)(u8 *buf, int count, void *data),
|
||||
void *priv)
|
||||
{
|
||||
dvb_filter_ipack_init(pa, IPACKS, pes_write);
|
||||
dvb_filter_ipack_init(pv, IPACKS, pes_write);
|
||||
pa->pid = pida;
|
||||
pv->pid = pidv;
|
||||
pa->data = priv;
|
||||
pv->data = priv;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static void ts_to_pes(ipack *p, u8 *buf) // don't need count (=188)
|
||||
{
|
||||
u8 off = 0;
|
||||
|
||||
if (!buf || !p ){
|
||||
printk("NULL POINTER IDIOT\n");
|
||||
return;
|
||||
}
|
||||
if (buf[1]&PAY_START) {
|
||||
if (p->plength == MMAX_PLENGTH-6 && p->found>6){
|
||||
p->plength = p->found-6;
|
||||
p->found = 0;
|
||||
send_ipack(p);
|
||||
dvb_filter_ipack_reset(p);
|
||||
}
|
||||
}
|
||||
if (buf[3] & ADAPT_FIELD) { // adaptation field?
|
||||
off = buf[4] + 1;
|
||||
if (off+4 > 187) return;
|
||||
}
|
||||
dvb_filter_instant_repack(buf+4+off, TS_SIZE-4-off, p);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* needs 5 byte input, returns picture coding type*/
|
||||
static int read_picture_header(u8 *headr, struct mpg_picture *pic, int field, int pr)
|
||||
{
|
||||
u8 pct;
|
||||
|
||||
if (pr) printk( "Pic header: ");
|
||||
pic->temporal_reference[field] = (( headr[0] << 2 ) |
|
||||
(headr[1] & 0x03) )& 0x03ff;
|
||||
if (pr) printk( " temp ref: 0x%04x", pic->temporal_reference[field]);
|
||||
|
||||
pct = ( headr[1] >> 2 ) & 0x07;
|
||||
pic->picture_coding_type[field] = pct;
|
||||
if (pr) {
|
||||
switch(pct){
|
||||
case I_FRAME:
|
||||
printk( " I-FRAME");
|
||||
break;
|
||||
case B_FRAME:
|
||||
printk( " B-FRAME");
|
||||
break;
|
||||
case P_FRAME:
|
||||
printk( " P-FRAME");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pic->vinfo.vbv_delay = (( headr[1] >> 5 ) | ( headr[2] << 3) |
|
||||
( (headr[3] & 0x1F) << 11) ) & 0xffff;
|
||||
|
||||
if (pr) printk( " vbv delay: 0x%04x", pic->vinfo.vbv_delay);
|
||||
|
||||
pic->picture_header_parameter = ( headr[3] & 0xe0 ) |
|
||||
((headr[4] & 0x80) >> 3);
|
||||
|
||||
if ( pct == B_FRAME ){
|
||||
pic->picture_header_parameter |= ( headr[4] >> 3 ) & 0x0f;
|
||||
}
|
||||
if (pr) printk( " pic head param: 0x%x",
|
||||
pic->picture_header_parameter);
|
||||
|
||||
return pct;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* needs 4 byte input */
|
||||
static int read_gop_header(u8 *headr, struct mpg_picture *pic, int pr)
|
||||
{
|
||||
if (pr) printk("GOP header: ");
|
||||
|
||||
pic->time_code = (( headr[0] << 17 ) | ( headr[1] << 9) |
|
||||
( headr[2] << 1 ) | (headr[3] &0x01)) & 0x1ffffff;
|
||||
|
||||
if (pr) printk(" time: %d:%d.%d ", (headr[0]>>2)& 0x1F,
|
||||
((headr[0]<<4)& 0x30)| ((headr[1]>>4)& 0x0F),
|
||||
((headr[1]<<3)& 0x38)| ((headr[2]>>5)& 0x0F));
|
||||
|
||||
if ( ( headr[3] & 0x40 ) != 0 ){
|
||||
pic->closed_gop = 1;
|
||||
} else {
|
||||
pic->closed_gop = 0;
|
||||
}
|
||||
if (pr) printk("closed: %d", pic->closed_gop);
|
||||
|
||||
if ( ( headr[3] & 0x20 ) != 0 ){
|
||||
pic->broken_link = 1;
|
||||
} else {
|
||||
pic->broken_link = 0;
|
||||
}
|
||||
if (pr) printk(" broken: %d\n", pic->broken_link);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* needs 8 byte input */
|
||||
static int read_sequence_header(u8 *headr, struct dvb_video_info *vi, int pr)
|
||||
{
|
||||
int sw;
|
||||
int form = -1;
|
||||
|
||||
if (pr) printk("Reading sequence header\n");
|
||||
|
||||
vi->horizontal_size = ((headr[1] &0xF0) >> 4) | (headr[0] << 4);
|
||||
vi->vertical_size = ((headr[1] &0x0F) << 8) | (headr[2]);
|
||||
|
||||
sw = (int)((headr[3]&0xF0) >> 4) ;
|
||||
|
||||
switch( sw ){
|
||||
case 1:
|
||||
if (pr)
|
||||
printk("Videostream: ASPECT: 1:1");
|
||||
vi->aspect_ratio = 100;
|
||||
break;
|
||||
case 2:
|
||||
if (pr)
|
||||
printk("Videostream: ASPECT: 4:3");
|
||||
vi->aspect_ratio = 133;
|
||||
break;
|
||||
case 3:
|
||||
if (pr)
|
||||
printk("Videostream: ASPECT: 16:9");
|
||||
vi->aspect_ratio = 177;
|
||||
break;
|
||||
case 4:
|
||||
if (pr)
|
||||
printk("Videostream: ASPECT: 2.21:1");
|
||||
vi->aspect_ratio = 221;
|
||||
break;
|
||||
|
||||
case 5 ... 15:
|
||||
if (pr)
|
||||
printk("Videostream: ASPECT: reserved");
|
||||
vi->aspect_ratio = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
vi->aspect_ratio = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pr)
|
||||
printk(" Size = %dx%d",vi->horizontal_size,vi->vertical_size);
|
||||
|
||||
sw = (int)(headr[3]&0x0F);
|
||||
|
||||
switch ( sw ) {
|
||||
case 1:
|
||||
if (pr)
|
||||
printk(" FRate: 23.976 fps");
|
||||
vi->framerate = 23976;
|
||||
form = -1;
|
||||
break;
|
||||
case 2:
|
||||
if (pr)
|
||||
printk(" FRate: 24 fps");
|
||||
vi->framerate = 24000;
|
||||
form = -1;
|
||||
break;
|
||||
case 3:
|
||||
if (pr)
|
||||
printk(" FRate: 25 fps");
|
||||
vi->framerate = 25000;
|
||||
form = VIDEO_MODE_PAL;
|
||||
break;
|
||||
case 4:
|
||||
if (pr)
|
||||
printk(" FRate: 29.97 fps");
|
||||
vi->framerate = 29970;
|
||||
form = VIDEO_MODE_NTSC;
|
||||
break;
|
||||
case 5:
|
||||
if (pr)
|
||||
printk(" FRate: 30 fps");
|
||||
vi->framerate = 30000;
|
||||
form = VIDEO_MODE_NTSC;
|
||||
break;
|
||||
case 6:
|
||||
if (pr)
|
||||
printk(" FRate: 50 fps");
|
||||
vi->framerate = 50000;
|
||||
form = VIDEO_MODE_PAL;
|
||||
break;
|
||||
case 7:
|
||||
if (pr)
|
||||
printk(" FRate: 60 fps");
|
||||
vi->framerate = 60000;
|
||||
form = VIDEO_MODE_NTSC;
|
||||
break;
|
||||
}
|
||||
|
||||
vi->bit_rate = (headr[4] << 10) | (headr[5] << 2) | (headr[6] & 0x03);
|
||||
|
||||
vi->vbv_buffer_size
|
||||
= (( headr[6] & 0xF8) >> 3 ) | (( headr[7] & 0x1F )<< 5);
|
||||
|
||||
if (pr){
|
||||
printk(" BRate: %d Mbit/s",4*(vi->bit_rate)/10000);
|
||||
printk(" vbvbuffer %d",16*1024*(vi->vbv_buffer_size));
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
vi->video_format = form;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
static int get_vinfo(u8 *mbuf, int count, struct dvb_video_info *vi, int pr)
|
||||
{
|
||||
u8 *headr;
|
||||
int found = 0;
|
||||
int c = 0;
|
||||
|
||||
while (found < 4 && c+4 < count){
|
||||
u8 *b;
|
||||
|
||||
b = mbuf+c;
|
||||
if ( b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01
|
||||
&& b[3] == 0xb3) found = 4;
|
||||
else {
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
if (! found) return -1;
|
||||
c += 4;
|
||||
if (c+12 >= count) return -1;
|
||||
headr = mbuf+c;
|
||||
if (read_sequence_header(headr, vi, pr) < 0) return -1;
|
||||
vi->off = c-4;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
static int get_ainfo(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr)
|
||||
{
|
||||
u8 *headr;
|
||||
int found = 0;
|
||||
int c = 0;
|
||||
int fr = 0;
|
||||
|
||||
while (found < 2 && c < count){
|
||||
u8 b[2];
|
||||
memcpy( b, mbuf+c, 2);
|
||||
|
||||
if ( b[0] == 0xff && (b[1] & 0xf8) == 0xf8)
|
||||
found = 2;
|
||||
else {
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) return -1;
|
||||
|
||||
if (c+3 >= count) return -1;
|
||||
headr = mbuf+c;
|
||||
|
||||
ai->layer = (headr[1] & 0x06) >> 1;
|
||||
|
||||
if (pr)
|
||||
printk("Audiostream: Layer: %d", 4-ai->layer);
|
||||
|
||||
|
||||
ai->bit_rate = bitrates[(3-ai->layer)][(headr[2] >> 4 )]*1000;
|
||||
|
||||
if (pr){
|
||||
if (ai->bit_rate == 0)
|
||||
printk(" Bit rate: free");
|
||||
else if (ai->bit_rate == 0xf)
|
||||
printk(" BRate: reserved");
|
||||
else
|
||||
printk(" BRate: %d kb/s", ai->bit_rate/1000);
|
||||
}
|
||||
|
||||
fr = (headr[2] & 0x0c ) >> 2;
|
||||
ai->frequency = freq[fr]*100;
|
||||
if (pr){
|
||||
if (ai->frequency == 3)
|
||||
printk(" Freq: reserved\n");
|
||||
else
|
||||
printk(" Freq: %d kHz\n",ai->frequency);
|
||||
|
||||
}
|
||||
ai->off = c;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr)
|
||||
{
|
||||
u8 *headr;
|
||||
int found = 0;
|
||||
int c = 0;
|
||||
u8 frame = 0;
|
||||
int fr = 0;
|
||||
|
||||
while ( !found && c < count){
|
||||
u8 *b = mbuf+c;
|
||||
|
||||
if ( b[0] == 0x0b && b[1] == 0x77 )
|
||||
found = 1;
|
||||
else {
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) return -1;
|
||||
if (pr)
|
||||
printk("Audiostream: AC3");
|
||||
|
||||
ai->off = c;
|
||||
if (c+5 >= count) return -1;
|
||||
|
||||
ai->layer = 0; // 0 for AC3
|
||||
headr = mbuf+c+2;
|
||||
|
||||
frame = (headr[2]&0x3f);
|
||||
ai->bit_rate = ac3_bitrates[frame >> 1]*1000;
|
||||
|
||||
if (pr)
|
||||
printk(" BRate: %d kb/s", (int) ai->bit_rate/1000);
|
||||
|
||||
ai->frequency = (headr[2] & 0xc0 ) >> 6;
|
||||
fr = (headr[2] & 0xc0 ) >> 6;
|
||||
ai->frequency = freq[fr]*100;
|
||||
if (pr) printk (" Freq: %d Hz\n", (int) ai->frequency);
|
||||
|
||||
|
||||
ai->framesize = ac3_frames[fr][frame >> 1];
|
||||
if ((frame & 1) && (fr == 1)) ai->framesize++;
|
||||
ai->framesize = ai->framesize << 1;
|
||||
if (pr) printk (" Framesize %d\n",(int) ai->framesize);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_filter_get_ac3info);
|
||||
|
||||
|
||||
#if 0
|
||||
static u8 *skip_pes_header(u8 **bufp)
|
||||
{
|
||||
u8 *inbuf = *bufp;
|
||||
u8 *buf = inbuf;
|
||||
u8 *pts = NULL;
|
||||
int skip = 0;
|
||||
|
||||
static const int mpeg1_skip_table[16] = {
|
||||
1, 0xffff, 5, 10, 0xffff, 0xffff, 0xffff, 0xffff,
|
||||
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
|
||||
};
|
||||
|
||||
|
||||
if ((inbuf[6] & 0xc0) == 0x80){ /* mpeg2 */
|
||||
if (buf[7] & PTS_ONLY)
|
||||
pts = buf+9;
|
||||
else pts = NULL;
|
||||
buf = inbuf + 9 + inbuf[8];
|
||||
} else { /* mpeg1 */
|
||||
for (buf = inbuf + 6; *buf == 0xff; buf++)
|
||||
if (buf == inbuf + 6 + 16) {
|
||||
break;
|
||||
}
|
||||
if ((*buf & 0xc0) == 0x40)
|
||||
buf += 2;
|
||||
skip = mpeg1_skip_table [*buf >> 4];
|
||||
if (skip == 5 || skip == 10) pts = buf;
|
||||
else pts = NULL;
|
||||
|
||||
buf += mpeg1_skip_table [*buf >> 4];
|
||||
}
|
||||
|
||||
*bufp = buf;
|
||||
return pts;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static void initialize_quant_matrix( u32 *matrix )
|
||||
{
|
||||
int i;
|
||||
|
||||
matrix[0] = 0x08101013;
|
||||
matrix[1] = 0x10131616;
|
||||
matrix[2] = 0x16161616;
|
||||
matrix[3] = 0x1a181a1b;
|
||||
matrix[4] = 0x1b1b1a1a;
|
||||
matrix[5] = 0x1a1a1b1b;
|
||||
matrix[6] = 0x1b1d1d1d;
|
||||
matrix[7] = 0x2222221d;
|
||||
matrix[8] = 0x1d1d1b1b;
|
||||
matrix[9] = 0x1d1d2020;
|
||||
matrix[10] = 0x22222526;
|
||||
matrix[11] = 0x25232322;
|
||||
matrix[12] = 0x23262628;
|
||||
matrix[13] = 0x28283030;
|
||||
matrix[14] = 0x2e2e3838;
|
||||
matrix[15] = 0x3a454553;
|
||||
|
||||
for ( i = 16 ; i < 32 ; i++ )
|
||||
matrix[i] = 0x10101010;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static void initialize_mpg_picture(struct mpg_picture *pic)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* set MPEG1 */
|
||||
pic->mpeg1_flag = 1;
|
||||
pic->profile_and_level = 0x4A ; /* MP@LL */
|
||||
pic->progressive_sequence = 1;
|
||||
pic->low_delay = 0;
|
||||
|
||||
pic->sequence_display_extension_flag = 0;
|
||||
for ( i = 0 ; i < 4 ; i++ ){
|
||||
pic->frame_centre_horizontal_offset[i] = 0;
|
||||
pic->frame_centre_vertical_offset[i] = 0;
|
||||
}
|
||||
pic->last_frame_centre_horizontal_offset = 0;
|
||||
pic->last_frame_centre_vertical_offset = 0;
|
||||
|
||||
pic->picture_display_extension_flag[0] = 0;
|
||||
pic->picture_display_extension_flag[1] = 0;
|
||||
pic->sequence_header_flag = 0;
|
||||
pic->gop_flag = 0;
|
||||
pic->sequence_end_flag = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static void mpg_set_picture_parameter( int32_t field_type, struct mpg_picture *pic )
|
||||
{
|
||||
int16_t last_h_offset;
|
||||
int16_t last_v_offset;
|
||||
|
||||
int16_t *p_h_offset;
|
||||
int16_t *p_v_offset;
|
||||
|
||||
if ( pic->mpeg1_flag ){
|
||||
pic->picture_structure[field_type] = VIDEO_FRAME_PICTURE;
|
||||
pic->top_field_first = 0;
|
||||
pic->repeat_first_field = 0;
|
||||
pic->progressive_frame = 1;
|
||||
pic->picture_coding_parameter = 0x000010;
|
||||
}
|
||||
|
||||
/* Reset flag */
|
||||
pic->picture_display_extension_flag[field_type] = 0;
|
||||
|
||||
last_h_offset = pic->last_frame_centre_horizontal_offset;
|
||||
last_v_offset = pic->last_frame_centre_vertical_offset;
|
||||
if ( field_type == FIRST_FIELD ){
|
||||
p_h_offset = pic->frame_centre_horizontal_offset;
|
||||
p_v_offset = pic->frame_centre_vertical_offset;
|
||||
*p_h_offset = last_h_offset;
|
||||
*(p_h_offset + 1) = last_h_offset;
|
||||
*(p_h_offset + 2) = last_h_offset;
|
||||
*p_v_offset = last_v_offset;
|
||||
*(p_v_offset + 1) = last_v_offset;
|
||||
*(p_v_offset + 2) = last_v_offset;
|
||||
} else {
|
||||
pic->frame_centre_horizontal_offset[3] = last_h_offset;
|
||||
pic->frame_centre_vertical_offset[3] = last_v_offset;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static void init_mpg_picture( struct mpg_picture *pic, int chan, int32_t field_type)
|
||||
{
|
||||
pic->picture_header = 0;
|
||||
pic->sequence_header_data
|
||||
= ( INIT_HORIZONTAL_SIZE << 20 )
|
||||
| ( INIT_VERTICAL_SIZE << 8 )
|
||||
| ( INIT_ASPECT_RATIO << 4 )
|
||||
| ( INIT_FRAME_RATE );
|
||||
pic->mpeg1_flag = 0;
|
||||
pic->vinfo.horizontal_size
|
||||
= INIT_DISP_HORIZONTAL_SIZE;
|
||||
pic->vinfo.vertical_size
|
||||
= INIT_DISP_VERTICAL_SIZE;
|
||||
pic->picture_display_extension_flag[field_type]
|
||||
= 0;
|
||||
pic->pts_flag[field_type] = 0;
|
||||
|
||||
pic->sequence_gop_header = 0;
|
||||
pic->picture_header = 0;
|
||||
pic->sequence_header_flag = 0;
|
||||
pic->gop_flag = 0;
|
||||
pic->sequence_end_flag = 0;
|
||||
pic->sequence_display_extension_flag = 0;
|
||||
pic->last_frame_centre_horizontal_offset = 0;
|
||||
pic->last_frame_centre_vertical_offset = 0;
|
||||
pic->channel = chan;
|
||||
}
|
||||
#endif
|
||||
|
||||
void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid,
|
||||
dvb_filter_pes2ts_cb_t *cb, void *priv)
|
||||
{
|
||||
unsigned char *buf=p2ts->buf;
|
||||
|
||||
buf[0]=0x47;
|
||||
buf[1]=(pid>>8);
|
||||
buf[2]=pid&0xff;
|
||||
p2ts->cc=0;
|
||||
p2ts->cb=cb;
|
||||
p2ts->priv=priv;
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_filter_pes2ts_init);
|
||||
|
||||
int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes,
|
||||
int len, int payload_start)
|
||||
{
|
||||
unsigned char *buf=p2ts->buf;
|
||||
int ret=0, rest;
|
||||
|
||||
//len=6+((pes[4]<<8)|pes[5]);
|
||||
|
||||
if (payload_start)
|
||||
buf[1]|=0x40;
|
||||
else
|
||||
buf[1]&=~0x40;
|
||||
while (len>=184) {
|
||||
buf[3]=0x10|((p2ts->cc++)&0x0f);
|
||||
memcpy(buf+4, pes, 184);
|
||||
if ((ret=p2ts->cb(p2ts->priv, buf)))
|
||||
return ret;
|
||||
len-=184; pes+=184;
|
||||
buf[1]&=~0x40;
|
||||
}
|
||||
if (!len)
|
||||
return 0;
|
||||
buf[3]=0x30|((p2ts->cc++)&0x0f);
|
||||
rest=183-len;
|
||||
if (rest) {
|
||||
buf[5]=0x00;
|
||||
if (rest-1)
|
||||
memset(buf+6, 0xff, rest-1);
|
||||
}
|
||||
buf[4]=rest;
|
||||
memcpy(buf+5+rest, pes, len);
|
||||
return p2ts->cb(p2ts->priv, buf);
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_filter_pes2ts);
|
@@ -1,246 +0,0 @@
|
||||
/*
|
||||
* dvb_filter.h
|
||||
*
|
||||
* Copyright (C) 2003 Convergence GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _DVB_FILTER_H_
|
||||
#define _DVB_FILTER_H_
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "demux.h"
|
||||
|
||||
typedef int (dvb_filter_pes2ts_cb_t) (void *, unsigned char *);
|
||||
|
||||
struct dvb_filter_pes2ts {
|
||||
unsigned char buf[188];
|
||||
unsigned char cc;
|
||||
dvb_filter_pes2ts_cb_t *cb;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid,
|
||||
dvb_filter_pes2ts_cb_t *cb, void *priv);
|
||||
|
||||
int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes,
|
||||
int len, int payload_start);
|
||||
|
||||
|
||||
#define PROG_STREAM_MAP 0xBC
|
||||
#define PRIVATE_STREAM1 0xBD
|
||||
#define PADDING_STREAM 0xBE
|
||||
#define PRIVATE_STREAM2 0xBF
|
||||
#define AUDIO_STREAM_S 0xC0
|
||||
#define AUDIO_STREAM_E 0xDF
|
||||
#define VIDEO_STREAM_S 0xE0
|
||||
#define VIDEO_STREAM_E 0xEF
|
||||
#define ECM_STREAM 0xF0
|
||||
#define EMM_STREAM 0xF1
|
||||
#define DSM_CC_STREAM 0xF2
|
||||
#define ISO13522_STREAM 0xF3
|
||||
#define PROG_STREAM_DIR 0xFF
|
||||
|
||||
#define DVB_PICTURE_START 0x00
|
||||
#define DVB_USER_START 0xb2
|
||||
#define DVB_SEQUENCE_HEADER 0xb3
|
||||
#define DVB_SEQUENCE_ERROR 0xb4
|
||||
#define DVB_EXTENSION_START 0xb5
|
||||
#define DVB_SEQUENCE_END 0xb7
|
||||
#define DVB_GOP_START 0xb8
|
||||
#define DVB_EXCEPT_SLICE 0xb0
|
||||
|
||||
#define SEQUENCE_EXTENSION 0x01
|
||||
#define SEQUENCE_DISPLAY_EXTENSION 0x02
|
||||
#define PICTURE_CODING_EXTENSION 0x08
|
||||
#define QUANT_MATRIX_EXTENSION 0x03
|
||||
#define PICTURE_DISPLAY_EXTENSION 0x07
|
||||
|
||||
#define I_FRAME 0x01
|
||||
#define B_FRAME 0x02
|
||||
#define P_FRAME 0x03
|
||||
|
||||
/* Initialize sequence_data */
|
||||
#define INIT_HORIZONTAL_SIZE 720
|
||||
#define INIT_VERTICAL_SIZE 576
|
||||
#define INIT_ASPECT_RATIO 0x02
|
||||
#define INIT_FRAME_RATE 0x03
|
||||
#define INIT_DISP_HORIZONTAL_SIZE 540
|
||||
#define INIT_DISP_VERTICAL_SIZE 576
|
||||
|
||||
|
||||
//flags2
|
||||
#define PTS_DTS_FLAGS 0xC0
|
||||
#define ESCR_FLAG 0x20
|
||||
#define ES_RATE_FLAG 0x10
|
||||
#define DSM_TRICK_FLAG 0x08
|
||||
#define ADD_CPY_FLAG 0x04
|
||||
#define PES_CRC_FLAG 0x02
|
||||
#define PES_EXT_FLAG 0x01
|
||||
|
||||
//pts_dts flags
|
||||
#define PTS_ONLY 0x80
|
||||
#define PTS_DTS 0xC0
|
||||
|
||||
#define TS_SIZE 188
|
||||
#define TRANS_ERROR 0x80
|
||||
#define PAY_START 0x40
|
||||
#define TRANS_PRIO 0x20
|
||||
#define PID_MASK_HI 0x1F
|
||||
//flags
|
||||
#define TRANS_SCRMBL1 0x80
|
||||
#define TRANS_SCRMBL2 0x40
|
||||
#define ADAPT_FIELD 0x20
|
||||
#define PAYLOAD 0x10
|
||||
#define COUNT_MASK 0x0F
|
||||
|
||||
// adaptation flags
|
||||
#define DISCON_IND 0x80
|
||||
#define RAND_ACC_IND 0x40
|
||||
#define ES_PRI_IND 0x20
|
||||
#define PCR_FLAG 0x10
|
||||
#define OPCR_FLAG 0x08
|
||||
#define SPLICE_FLAG 0x04
|
||||
#define TRANS_PRIV 0x02
|
||||
#define ADAP_EXT_FLAG 0x01
|
||||
|
||||
// adaptation extension flags
|
||||
#define LTW_FLAG 0x80
|
||||
#define PIECE_RATE 0x40
|
||||
#define SEAM_SPLICE 0x20
|
||||
|
||||
|
||||
#define MAX_PLENGTH 0xFFFF
|
||||
#define MMAX_PLENGTH (256*MAX_PLENGTH)
|
||||
|
||||
#ifndef IPACKS
|
||||
#define IPACKS 2048
|
||||
#endif
|
||||
|
||||
struct ipack {
|
||||
int size;
|
||||
int found;
|
||||
u8 *buf;
|
||||
u8 cid;
|
||||
u32 plength;
|
||||
u8 plen[2];
|
||||
u8 flag1;
|
||||
u8 flag2;
|
||||
u8 hlength;
|
||||
u8 pts[5];
|
||||
u16 *pid;
|
||||
int mpeg;
|
||||
u8 check;
|
||||
int which;
|
||||
int done;
|
||||
void *data;
|
||||
void (*func)(u8 *buf, int size, void *priv);
|
||||
int count;
|
||||
int repack_subids;
|
||||
};
|
||||
|
||||
struct dvb_video_info {
|
||||
u32 horizontal_size;
|
||||
u32 vertical_size;
|
||||
u32 aspect_ratio;
|
||||
u32 framerate;
|
||||
u32 video_format;
|
||||
u32 bit_rate;
|
||||
u32 comp_bit_rate;
|
||||
u32 vbv_buffer_size;
|
||||
s16 vbv_delay;
|
||||
u32 CSPF;
|
||||
u32 off;
|
||||
};
|
||||
|
||||
#define OFF_SIZE 4
|
||||
#define FIRST_FIELD 0
|
||||
#define SECOND_FIELD 1
|
||||
#define VIDEO_FRAME_PICTURE 0x03
|
||||
|
||||
struct mpg_picture {
|
||||
int channel;
|
||||
struct dvb_video_info vinfo;
|
||||
u32 *sequence_gop_header;
|
||||
u32 *picture_header;
|
||||
s32 time_code;
|
||||
int low_delay;
|
||||
int closed_gop;
|
||||
int broken_link;
|
||||
int sequence_header_flag;
|
||||
int gop_flag;
|
||||
int sequence_end_flag;
|
||||
|
||||
u8 profile_and_level;
|
||||
s32 picture_coding_parameter;
|
||||
u32 matrix[32];
|
||||
s8 matrix_change_flag;
|
||||
|
||||
u8 picture_header_parameter;
|
||||
/* bit 0 - 2: bwd f code
|
||||
bit 3 : fpb vector
|
||||
bit 4 - 6: fwd f code
|
||||
bit 7 : fpf vector */
|
||||
|
||||
int mpeg1_flag;
|
||||
int progressive_sequence;
|
||||
int sequence_display_extension_flag;
|
||||
u32 sequence_header_data;
|
||||
s16 last_frame_centre_horizontal_offset;
|
||||
s16 last_frame_centre_vertical_offset;
|
||||
|
||||
u32 pts[2]; /* [0] 1st field, [1] 2nd field */
|
||||
int top_field_first;
|
||||
int repeat_first_field;
|
||||
int progressive_frame;
|
||||
int bank;
|
||||
int forward_bank;
|
||||
int backward_bank;
|
||||
int compress;
|
||||
s16 frame_centre_horizontal_offset[OFF_SIZE];
|
||||
/* [0-2] 1st field, [3] 2nd field */
|
||||
s16 frame_centre_vertical_offset[OFF_SIZE];
|
||||
/* [0-2] 1st field, [3] 2nd field */
|
||||
s16 temporal_reference[2];
|
||||
/* [0] 1st field, [1] 2nd field */
|
||||
|
||||
s8 picture_coding_type[2];
|
||||
/* [0] 1st field, [1] 2nd field */
|
||||
s8 picture_structure[2];
|
||||
/* [0] 1st field, [1] 2nd field */
|
||||
s8 picture_display_extension_flag[2];
|
||||
/* [0] 1st field, [1] 2nd field */
|
||||
/* picture_display_extenion() 0:no 1:exit*/
|
||||
s8 pts_flag[2];
|
||||
/* [0] 1st field, [1] 2nd field */
|
||||
};
|
||||
|
||||
struct dvb_audio_info {
|
||||
int layer;
|
||||
u32 bit_rate;
|
||||
u32 frequency;
|
||||
u32 mode;
|
||||
u32 mode_extension ;
|
||||
u32 emphasis;
|
||||
u32 framesize;
|
||||
u32 off;
|
||||
};
|
||||
|
||||
int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr);
|
||||
|
||||
|
||||
#endif
|
@@ -28,6 +28,8 @@
|
||||
/* Enables DVBv3 compatibility bits at the headers */
|
||||
#define __DVB_CORE__
|
||||
|
||||
#define pr_fmt(fmt) "dvb_frontend: " fmt
|
||||
|
||||
#include <linux/string.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
@@ -67,6 +69,9 @@ MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB volt
|
||||
module_param(dvb_mfe_wait_time, int, 0644);
|
||||
MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open() for multi-frontend to become available (default:5 seconds)");
|
||||
|
||||
#define dprintk(fmt, arg...) \
|
||||
printk(KERN_DEBUG pr_fmt("%s: " fmt), __func__, ##arg)
|
||||
|
||||
#define FESTATE_IDLE 1
|
||||
#define FESTATE_RETUNE 2
|
||||
#define FESTATE_TUNING_FAST 4
|
||||
@@ -99,8 +104,6 @@ MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open(
|
||||
static DEFINE_MUTEX(frontend_mutex);
|
||||
|
||||
struct dvb_frontend_private {
|
||||
struct kref refcount;
|
||||
|
||||
/* thread/frontend values */
|
||||
struct dvb_device *dvbdev;
|
||||
struct dvb_frontend_parameters parameters_out;
|
||||
@@ -138,21 +141,30 @@ struct dvb_frontend_private {
|
||||
#endif
|
||||
};
|
||||
|
||||
static void dvb_frontend_private_free(struct kref *ref)
|
||||
static void dvb_frontend_invoke_release(struct dvb_frontend *fe,
|
||||
void (*release)(struct dvb_frontend *fe));
|
||||
|
||||
static void dvb_frontend_free(struct kref *ref)
|
||||
{
|
||||
struct dvb_frontend_private *fepriv =
|
||||
container_of(ref, struct dvb_frontend_private, refcount);
|
||||
struct dvb_frontend *fe =
|
||||
container_of(ref, struct dvb_frontend, refcount);
|
||||
struct dvb_frontend_private *fepriv = fe->frontend_priv;
|
||||
|
||||
dvb_free_device(fepriv->dvbdev);
|
||||
|
||||
dvb_frontend_invoke_release(fe, fe->ops.release);
|
||||
|
||||
kfree(fepriv);
|
||||
}
|
||||
|
||||
static void dvb_frontend_private_put(struct dvb_frontend_private *fepriv)
|
||||
static void dvb_frontend_put(struct dvb_frontend *fe)
|
||||
{
|
||||
kref_put(&fepriv->refcount, dvb_frontend_private_free);
|
||||
kref_put(&fe->refcount, dvb_frontend_free);
|
||||
}
|
||||
|
||||
static void dvb_frontend_private_get(struct dvb_frontend_private *fepriv)
|
||||
static void dvb_frontend_get(struct dvb_frontend *fe)
|
||||
{
|
||||
kref_get(&fepriv->refcount);
|
||||
kref_get(&fe->refcount);
|
||||
}
|
||||
|
||||
static void dvb_frontend_wakeup(struct dvb_frontend *fe);
|
||||
@@ -1515,12 +1527,8 @@ static int dtv_set_frontend(struct dvb_frontend *fe);
|
||||
|
||||
static bool is_dvbv3_delsys(u32 delsys)
|
||||
{
|
||||
bool status;
|
||||
|
||||
status = (delsys == SYS_DVBT) || (delsys == SYS_DVBC_ANNEX_A) ||
|
||||
(delsys == SYS_DVBS) || (delsys == SYS_ATSC);
|
||||
|
||||
return status;
|
||||
return (delsys == SYS_DVBT) || (delsys == SYS_DVBC_ANNEX_A) ||
|
||||
(delsys == SYS_DVBS) || (delsys == SYS_ATSC);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2356,7 +2364,8 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
|
||||
int i;
|
||||
u8 last = 1;
|
||||
if (dvb_frontend_debug)
|
||||
printk("%s switch command: 0x%04lx\n", __func__, swcmd);
|
||||
dprintk("%s switch command: 0x%04lx\n",
|
||||
__func__, swcmd);
|
||||
nexttime = ktime_get_boottime();
|
||||
if (dvb_frontend_debug)
|
||||
tv[0] = nexttime;
|
||||
@@ -2379,10 +2388,10 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
|
||||
dvb_frontend_sleep_until(&nexttime, 8000);
|
||||
}
|
||||
if (dvb_frontend_debug) {
|
||||
printk("%s(%d): switch delay (should be 32k followed by all 8k\n",
|
||||
dprintk("%s(%d): switch delay (should be 32k followed by all 8k)\n",
|
||||
__func__, fe->dvb->num);
|
||||
for (i = 1; i < 10; i++)
|
||||
printk("%d: %d\n", i,
|
||||
pr_info("%d: %d\n", i,
|
||||
(int) ktime_us_delta(tv[i], tv[i-1]));
|
||||
}
|
||||
err = 0;
|
||||
@@ -2545,7 +2554,7 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
|
||||
fepriv->events.eventr = fepriv->events.eventw = 0;
|
||||
}
|
||||
|
||||
dvb_frontend_private_get(fepriv);
|
||||
dvb_frontend_get(fe);
|
||||
|
||||
if (adapter->mfe_shared)
|
||||
mutex_unlock (&adapter->mfe_lock);
|
||||
@@ -2595,7 +2604,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
|
||||
fe->ops.ts_bus_ctrl(fe, 0);
|
||||
}
|
||||
|
||||
dvb_frontend_private_put(fepriv);
|
||||
dvb_frontend_put(fe);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -2685,7 +2694,14 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
|
||||
}
|
||||
fepriv = fe->frontend_priv;
|
||||
|
||||
kref_init(&fepriv->refcount);
|
||||
kref_init(&fe->refcount);
|
||||
|
||||
/*
|
||||
* After initialization, there need to be two references: one
|
||||
* for dvb_unregister_frontend(), and another one for
|
||||
* dvb_frontend_detach().
|
||||
*/
|
||||
dvb_frontend_get(fe);
|
||||
|
||||
sema_init(&fepriv->sem, 1);
|
||||
init_waitqueue_head (&fepriv->wait_queue);
|
||||
@@ -2720,50 +2736,33 @@ int dvb_unregister_frontend(struct dvb_frontend* fe)
|
||||
dev_dbg(fe->dvb->device, "%s:\n", __func__);
|
||||
|
||||
mutex_lock(&frontend_mutex);
|
||||
dvb_frontend_stop (fe);
|
||||
dvb_unregister_device (fepriv->dvbdev);
|
||||
dvb_frontend_stop(fe);
|
||||
dvb_remove_device(fepriv->dvbdev);
|
||||
|
||||
/* fe is invalid now */
|
||||
mutex_unlock(&frontend_mutex);
|
||||
dvb_frontend_private_put(fepriv);
|
||||
dvb_frontend_put(fe);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_unregister_frontend);
|
||||
|
||||
static void dvb_frontend_invoke_release(struct dvb_frontend *fe,
|
||||
void (*release)(struct dvb_frontend *fe))
|
||||
{
|
||||
if (release) {
|
||||
release(fe);
|
||||
#ifdef CONFIG_MEDIA_ATTACH
|
||||
void dvb_frontend_detach(struct dvb_frontend* fe)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
if (fe->ops.release_sec) {
|
||||
fe->ops.release_sec(fe);
|
||||
dvb_detach(fe->ops.release_sec);
|
||||
}
|
||||
if (fe->ops.tuner_ops.release) {
|
||||
fe->ops.tuner_ops.release(fe);
|
||||
dvb_detach(fe->ops.tuner_ops.release);
|
||||
}
|
||||
if (fe->ops.analog_ops.release) {
|
||||
fe->ops.analog_ops.release(fe);
|
||||
dvb_detach(fe->ops.analog_ops.release);
|
||||
}
|
||||
ptr = (void*)fe->ops.release;
|
||||
if (ptr) {
|
||||
fe->ops.release(fe);
|
||||
dvb_detach(ptr);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void dvb_frontend_detach(struct dvb_frontend* fe)
|
||||
{
|
||||
if (fe->ops.release_sec)
|
||||
fe->ops.release_sec(fe);
|
||||
if (fe->ops.tuner_ops.release)
|
||||
fe->ops.tuner_ops.release(fe);
|
||||
if (fe->ops.analog_ops.release)
|
||||
fe->ops.analog_ops.release(fe);
|
||||
if (fe->ops.release)
|
||||
fe->ops.release(fe);
|
||||
}
|
||||
dvb_detach(release);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void dvb_frontend_detach(struct dvb_frontend* fe)
|
||||
{
|
||||
dvb_frontend_invoke_release(fe, fe->ops.release_sec);
|
||||
dvb_frontend_invoke_release(fe, fe->ops.tuner_ops.release);
|
||||
dvb_frontend_invoke_release(fe, fe->ops.analog_ops.release);
|
||||
dvb_frontend_invoke_release(fe, fe->ops.detach);
|
||||
dvb_frontend_put(fe);
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_frontend_detach);
|
||||
|
@@ -225,7 +225,7 @@ struct dvb_tuner_ops {
|
||||
|
||||
struct dvb_tuner_info info;
|
||||
|
||||
int (*release)(struct dvb_frontend *fe);
|
||||
void (*release)(struct dvb_frontend *fe);
|
||||
int (*init)(struct dvb_frontend *fe);
|
||||
int (*sleep)(struct dvb_frontend *fe);
|
||||
int (*suspend)(struct dvb_frontend *fe);
|
||||
@@ -323,7 +323,11 @@ struct dtv_frontend_properties;
|
||||
*
|
||||
* @info: embedded struct dvb_tuner_info with tuner properties
|
||||
* @delsys: Delivery systems supported by the frontend
|
||||
* @release: callback function called when frontend is dettached.
|
||||
* @detach: callback function called when frontend is detached.
|
||||
* drivers should clean up, but not yet free the struct
|
||||
* dvb_frontend allocation.
|
||||
* @release: callback function called when frontend is ready to be
|
||||
* freed.
|
||||
* drivers should free any allocated memory.
|
||||
* @release_sec: callback function requesting that the Satelite Equipment
|
||||
* Control (SEC) driver to release and free any memory
|
||||
@@ -408,6 +412,7 @@ struct dvb_frontend_ops {
|
||||
|
||||
u8 delsys[MAX_DELSYS];
|
||||
|
||||
void (*detach)(struct dvb_frontend *fe);
|
||||
void (*release)(struct dvb_frontend* fe);
|
||||
void (*release_sec)(struct dvb_frontend* fe);
|
||||
|
||||
@@ -655,6 +660,7 @@ struct dtv_frontend_properties {
|
||||
*/
|
||||
|
||||
struct dvb_frontend {
|
||||
struct kref refcount;
|
||||
struct dvb_frontend_ops ops;
|
||||
struct dvb_adapter *dvb;
|
||||
void *demodulator_priv;
|
||||
|
A különbségek nem kerülnek megjelenítésre, mivel a fájl túl nagy
Load Diff
@@ -21,6 +21,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "dvbdev: " fmt
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/string.h>
|
||||
@@ -43,7 +45,11 @@ static int dvbdev_debug;
|
||||
module_param(dvbdev_debug, int, 0644);
|
||||
MODULE_PARM_DESC(dvbdev_debug, "Turn on/off device debugging (default:off).");
|
||||
|
||||
#define dprintk if (dvbdev_debug) printk
|
||||
#define dprintk(fmt, arg...) do { \
|
||||
if (dvbdev_debug) \
|
||||
printk(KERN_DEBUG pr_fmt("%s: " fmt), \
|
||||
__func__, ##arg); \
|
||||
} while (0)
|
||||
|
||||
static LIST_HEAD(dvb_adapter_list);
|
||||
static DEFINE_MUTEX(dvbdev_register_lock);
|
||||
@@ -354,7 +360,7 @@ static int dvb_create_media_entity(struct dvb_device *dvbdev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
printk(KERN_DEBUG "%s: media entity '%s' registered.\n",
|
||||
pr_info("%s: media entity '%s' registered.\n",
|
||||
__func__, dvbdev->entity->name);
|
||||
|
||||
return 0;
|
||||
@@ -438,7 +444,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
|
||||
if ((id = dvbdev_get_free_id (adap, type)) < 0){
|
||||
mutex_unlock(&dvbdev_register_lock);
|
||||
*pdvbdev = NULL;
|
||||
printk(KERN_ERR "%s: couldn't find free device id\n", __func__);
|
||||
pr_err("%s: couldn't find free device id\n", __func__);
|
||||
return -ENFILE;
|
||||
}
|
||||
|
||||
@@ -493,8 +499,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
|
||||
|
||||
ret = dvb_register_media_device(dvbdev, type, minor, demux_sink_pads);
|
||||
if (ret) {
|
||||
printk(KERN_ERR
|
||||
"%s: dvb_register_media_device failed to create the mediagraph\n",
|
||||
pr_err("%s: dvb_register_media_device failed to create the mediagraph\n",
|
||||
__func__);
|
||||
|
||||
dvb_media_device_free(dvbdev);
|
||||
@@ -511,11 +516,11 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
|
||||
MKDEV(DVB_MAJOR, minor),
|
||||
dvbdev, "dvb%d.%s%d", adap->num, dnames[type], id);
|
||||
if (IS_ERR(clsdev)) {
|
||||
printk(KERN_ERR "%s: failed to create device dvb%d.%s%d (%ld)\n",
|
||||
pr_err("%s: failed to create device dvb%d.%s%d (%ld)\n",
|
||||
__func__, adap->num, dnames[type], id, PTR_ERR(clsdev));
|
||||
return PTR_ERR(clsdev);
|
||||
}
|
||||
dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
|
||||
dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
|
||||
adap->num, dnames[type], id, minor, minor);
|
||||
|
||||
return 0;
|
||||
@@ -523,7 +528,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
|
||||
EXPORT_SYMBOL(dvb_register_device);
|
||||
|
||||
|
||||
void dvb_unregister_device(struct dvb_device *dvbdev)
|
||||
void dvb_remove_device(struct dvb_device *dvbdev)
|
||||
{
|
||||
if (!dvbdev)
|
||||
return;
|
||||
@@ -537,9 +542,26 @@ void dvb_unregister_device(struct dvb_device *dvbdev)
|
||||
device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor));
|
||||
|
||||
list_del (&dvbdev->list_head);
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_remove_device);
|
||||
|
||||
|
||||
void dvb_free_device(struct dvb_device *dvbdev)
|
||||
{
|
||||
if (!dvbdev)
|
||||
return;
|
||||
|
||||
kfree (dvbdev->fops);
|
||||
kfree (dvbdev);
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_free_device);
|
||||
|
||||
|
||||
void dvb_unregister_device(struct dvb_device *dvbdev)
|
||||
{
|
||||
dvb_remove_device(dvbdev);
|
||||
dvb_free_device(dvbdev);
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_unregister_device);
|
||||
|
||||
|
||||
@@ -808,7 +830,7 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
|
||||
memset (adap, 0, sizeof(struct dvb_adapter));
|
||||
INIT_LIST_HEAD (&adap->device_list);
|
||||
|
||||
printk(KERN_INFO "DVB: registering new adapter (%s)\n", name);
|
||||
pr_info("DVB: registering new adapter (%s)\n", name);
|
||||
|
||||
adap->num = num;
|
||||
adap->name = name;
|
||||
@@ -926,13 +948,13 @@ static int __init init_dvbdev(void)
|
||||
dev_t dev = MKDEV(DVB_MAJOR, 0);
|
||||
|
||||
if ((retval = register_chrdev_region(dev, MAX_DVB_MINORS, "DVB")) != 0) {
|
||||
printk(KERN_ERR "dvb-core: unable to get major %d\n", DVB_MAJOR);
|
||||
pr_err("dvb-core: unable to get major %d\n", DVB_MAJOR);
|
||||
return retval;
|
||||
}
|
||||
|
||||
cdev_init(&dvb_device_cdev, &dvb_device_fops);
|
||||
if ((retval = cdev_add(&dvb_device_cdev, dev, MAX_DVB_MINORS)) != 0) {
|
||||
printk(KERN_ERR "dvb-core: unable register character device\n");
|
||||
pr_err("dvb-core: unable register character device\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@@ -34,7 +34,7 @@
|
||||
#if defined(CONFIG_DVB_MAX_ADAPTERS) && CONFIG_DVB_MAX_ADAPTERS > 0
|
||||
#define DVB_MAX_ADAPTERS CONFIG_DVB_MAX_ADAPTERS
|
||||
#else
|
||||
#define DVB_MAX_ADAPTERS 8
|
||||
#define DVB_MAX_ADAPTERS 16
|
||||
#endif
|
||||
|
||||
#define DVB_UNSET (-1)
|
||||
@@ -211,9 +211,32 @@ int dvb_register_device(struct dvb_adapter *adap,
|
||||
int type,
|
||||
int demux_sink_pads);
|
||||
|
||||
/**
|
||||
* dvb_remove_device - Remove a registered DVB device
|
||||
*
|
||||
* This does not free memory. To do that, call dvb_free_device().
|
||||
*
|
||||
* @dvbdev: pointer to struct dvb_device
|
||||
*/
|
||||
void dvb_remove_device(struct dvb_device *dvbdev);
|
||||
|
||||
/**
|
||||
* dvb_free_device - Free memory occupied by a DVB device.
|
||||
*
|
||||
* Call dvb_unregister_device() before calling this function.
|
||||
*
|
||||
* @dvbdev: pointer to struct dvb_device
|
||||
*/
|
||||
void dvb_free_device(struct dvb_device *dvbdev);
|
||||
|
||||
/**
|
||||
* dvb_unregister_device - Unregisters a DVB device
|
||||
*
|
||||
* This is a combination of dvb_remove_device() and dvb_free_device().
|
||||
* Using this function is usually a mistake, and is often an indicator
|
||||
* for a use-after-free bug (when a userspace process keeps a file
|
||||
* handle to a detached device).
|
||||
*
|
||||
* @dvbdev: pointer to struct dvb_device
|
||||
*/
|
||||
void dvb_unregister_device(struct dvb_device *dvbdev);
|
||||
|
Reference in New Issue
Block a user