diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-07-08 07:25:08 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-07-08 07:25:08 -0300 |
commit | c13f70467621e2c352f93b336b382e70ea24d218 (patch) | |
tree | 582367340fe7529eb3fec3c514ec9d4b2f68ff71 | |
parent | a953cf4edb8db13f8b7d20c793696a13ffcd3333 (diff) | |
parent | 9380e197397e3f8404fa2d2effe5c84b6f56735b (diff) | |
download | mediapointer-dvb-s2-c13f70467621e2c352f93b336b382e70ea24d218.tar.gz mediapointer-dvb-s2-c13f70467621e2c352f93b336b382e70ea24d218.tar.bz2 |
merge: http://linuxtv.org/hg/~jfrancois/gspca/
From: Mauro Carvalho Chehab <mchehab@infradead.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
158 files changed, 9491 insertions, 2240 deletions
diff --git a/README.patches b/README.patches index 53b5c8a8a..882482223 100644 --- a/README.patches +++ b/README.patches @@ -281,8 +281,10 @@ j) Sometimes it is necessary to introduce some testing code inside a To allow compatibility tests, linux/version.h is automatically included by the building system. This allows adding tests like: - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - #include <linux/kthread.h> + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 16) + #include <linux/mutex.h> + #else + #include <asm/semaphore.h> #endif It should be noticed, however, that an explicit inclusion of diff --git a/linux/drivers/media/common/tuners/mt20xx.c b/linux/drivers/media/common/tuners/mt20xx.c index d2c281aeb..9d9f1cf11 100644 --- a/linux/drivers/media/common/tuners/mt20xx.c +++ b/linux/drivers/media/common/tuners/mt20xx.c @@ -10,9 +10,6 @@ #include <linux/videodev.h> #include "tuner-i2c.h" #include "mt20xx.h" -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include "i2c-compat.h" -#endif static int debug; module_param(debug, int, 0644); diff --git a/linux/drivers/media/common/tuners/tda8290.c b/linux/drivers/media/common/tuners/tda8290.c index 9bda53be5..751845554 100644 --- a/linux/drivers/media/common/tuners/tda8290.c +++ b/linux/drivers/media/common/tuners/tda8290.c @@ -28,9 +28,6 @@ #include "tda8290.h" #include "tda827x.h" #include "tda18271.h" -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include "i2c-compat.h" -#endif static int debug; module_param(debug, int, 0644); diff --git a/linux/drivers/media/common/tuners/tda9887.c b/linux/drivers/media/common/tuners/tda9887.c index e98de7d40..61a56026d 100644 --- a/linux/drivers/media/common/tuners/tda9887.c +++ b/linux/drivers/media/common/tuners/tda9887.c @@ -8,9 +8,6 @@ #include <linux/delay.h> #include "compat.h" #include <linux/videodev.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include "i2c-compat.h" -#endif #include <media/v4l2-common.h> #include <media/tuner.h> #include "tuner-i2c.h" @@ -438,17 +435,10 @@ static unsigned int port2 = UNSET; static unsigned int qss = UNSET; static unsigned int adjust = UNSET; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -MODULE_PARM(port1, "i"); -MODULE_PARM(port2, "i"); -MODULE_PARM(qss, "i"); -MODULE_PARM(adjust, "i"); -#else module_param(port1, int, 0644); module_param(port2, int, 0644); module_param(qss, int, 0644); module_param(adjust, int, 0644); -#endif static int tda9887_set_insmod(struct dvb_frontend *fe) { diff --git a/linux/drivers/media/common/tuners/tea5767.c b/linux/drivers/media/common/tuners/tea5767.c index 5990a63ef..c56ff2dc1 100644 --- a/linux/drivers/media/common/tuners/tea5767.c +++ b/linux/drivers/media/common/tuners/tea5767.c @@ -16,9 +16,6 @@ #include <linux/videodev.h> #include "tuner-i2c.h" #include "tea5767.h" -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include "i2c-compat.h" -#endif static int debug; module_param(debug, int, 0644); diff --git a/linux/drivers/media/common/tuners/tuner-simple.c b/linux/drivers/media/common/tuners/tuner-simple.c index c9d70e4b2..a029cf8f5 100644 --- a/linux/drivers/media/common/tuners/tuner-simple.c +++ b/linux/drivers/media/common/tuners/tuner-simple.c @@ -11,9 +11,6 @@ #include <media/tuner.h> #include <media/v4l2-common.h> #include <media/tuner-types.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include "i2c-compat.h" -#endif #include "tuner-i2c.h" #include "tuner-simple.h" @@ -25,11 +22,7 @@ MODULE_PARM_DESC(debug, "enable verbose debug messages"); static unsigned int simple_devcount; static int offset; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -MODULE_PARM(offset, "i"); -#else module_param(offset, int, 0664); -#endif MODULE_PARM_DESC(offset, "Allows to specify an offset for tuner"); static unsigned int atv_input[TUNER_SIMPLE_MAX] = \ diff --git a/linux/drivers/media/common/tuners/tuner-xc2028.c b/linux/drivers/media/common/tuners/tuner-xc2028.c index c51a7b4c8..9d3f397e3 100644 --- a/linux/drivers/media/common/tuners/tuner-xc2028.c +++ b/linux/drivers/media/common/tuners/tuner-xc2028.c @@ -22,9 +22,6 @@ #include "compat.h" #include <asm/unaligned.h> #include "tuner-i2c.h" -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -#include "i2c-compat.h" -#endif #include "tuner-xc2028.h" #include "tuner-xc2028-types.h" diff --git a/linux/drivers/media/dvb/cinergyT2/cinergyT2.c b/linux/drivers/media/dvb/cinergyT2/cinergyT2.c index 651df056e..e1d76b111 100644 --- a/linux/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/linux/drivers/media/dvb/cinergyT2/cinergyT2.c @@ -1086,12 +1086,6 @@ static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state) if (mutex_lock_interruptible(&cinergyt2->wq_sem)) return -ERESTARTSYS; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) - if (state <= 0) { - mutex_unlock(&cinergyt2->wq_sem); - return 0; - } -#endif cinergyt2_suspend_rc(cinergyt2); cancel_rearming_delayed_work(&cinergyt2->query_work); diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.c b/linux/drivers/media/dvb/dvb-core/dvbdev.c index 3439ccec6..2da27de38 100644 --- a/linux/drivers/media/dvb/dvb-core/dvbdev.c +++ b/linux/drivers/media/dvb/dvb-core/dvbdev.c @@ -56,11 +56,7 @@ static const char * const dnames[] = { #define nums2minor(num,type,id) ((num << 6) | (id << 4) | type) #define MAX_DVB_MINORS (DVB_MAX_ADAPTERS*64) -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13) static struct class *dvb_class; -#else -static struct class_simple *dvb_class; -#endif static struct dvb_device* dvbdev_find_device (int minor) { diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c index c4d40fe01..3dd20bfbe 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -1117,6 +1117,7 @@ struct usb_device_id dib0700_usb_id_table[] = { { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_EXPRESS) }, { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS) }, { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) }, + { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -1372,7 +1373,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { } }, - .num_device_descs = 2, + .num_device_descs = 3, .devices = { { "DiBcom STK7070PD reference design", { &dib0700_usb_id_table[17], NULL }, @@ -1381,6 +1382,10 @@ struct dvb_usb_device_properties dib0700_devices[] = { { "Pinnacle PCTV Dual DVB-T Diversity Stick", { &dib0700_usb_id_table[18], NULL }, { NULL }, + }, + { "Hauppauge Nova-TD Stick (52009)", + { &dib0700_usb_id_table[35], NULL }, + { NULL }, } } }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/linux/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c index 23428cd30..326f76089 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c @@ -20,11 +20,7 @@ int dvb_usb_i2c_init(struct dvb_usb_device *d) } strncpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name)); -#ifdef I2C_ADAP_CLASS_TV_DIGITAL - d->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL, -#else d->i2c_adap.class = I2C_CLASS_TV_DIGITAL, -#endif d->i2c_adap.algo = d->props.i2c_algo; d->i2c_adap.algo_data = NULL; d->i2c_adap.dev.parent = &d->udev->dev; diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 75ec9caa1..e5238b31e 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -134,6 +134,7 @@ #define USB_PID_HAUPPAUGE_NOVA_T_STICK_3 0x7070 #define USB_PID_HAUPPAUGE_MYTV_T 0x7080 #define USB_PID_HAUPPAUGE_NOVA_TD_STICK 0x9580 +#define USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009 0x5200 #define USB_PID_AVERMEDIA_EXPRESS 0xb568 #define USB_PID_AVERMEDIA_VOLAR 0xa807 #define USB_PID_AVERMEDIA_VOLAR_2 0xb808 diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c index b47427ea6..b2fae925a 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c @@ -9,10 +9,8 @@ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) #include <linux/usb/input.h> #else -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13) #include <linux/usb_input.h> #endif -#endif /* Remote-control poll function - called every dib->rc_query_interval ms to see * whether the remote control has received anything. diff --git a/linux/drivers/media/dvb/ttpci/av7110.c b/linux/drivers/media/dvb/ttpci/av7110.c index 04e1bcd6a..0909eb861 100644 --- a/linux/drivers/media/dvb/ttpci/av7110.c +++ b/linux/drivers/media/dvb/ttpci/av7110.c @@ -2471,11 +2471,7 @@ static int __devinit av7110_attach(struct saa7146_dev* dev, get recognized before the main driver is fully loaded */ saa7146_write(dev, GPIO_CTRL, 0x500000); -#ifdef I2C_ADAP_CLASS_TV_DIGITAL - av7110->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL; -#else av7110->i2c_adap.class = I2C_CLASS_TV_DIGITAL; -#endif strlcpy(av7110->i2c_adap.name, pci_ext->ext_priv, sizeof(av7110->i2c_adap.name)); saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */ diff --git a/linux/drivers/media/dvb/ttpci/av7110_ir.c b/linux/drivers/media/dvb/ttpci/av7110_ir.c index 18171c051..084164147 100644 --- a/linux/drivers/media/dvb/ttpci/av7110_ir.c +++ b/linux/drivers/media/dvb/ttpci/av7110_ir.c @@ -345,7 +345,6 @@ int __devinit av7110_ir_init(struct av7110 *av7110) input_dev->name = "DVB on-card IR receiver"; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) input_dev->phys = av7110->ir.input_phys; input_dev->id.bustype = BUS_PCI; input_dev->id.version = 2; @@ -365,7 +364,6 @@ int __devinit av7110_ir_init(struct av7110 *av7110) input_dev->dev = &av7110->dev->pci->dev; #endif #endif -#endif /* initial keymap */ memcpy(av7110->ir.key_map, default_key_map, sizeof av7110->ir.key_map); input_register_keys(&av7110->ir); diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index c254ff242..8234c397c 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -198,7 +198,6 @@ static int msp430_ir_init(struct budget_ci *budget_ci) input_dev->name = budget_ci->ir.name; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) input_dev->phys = budget_ci->ir.phys; input_dev->id.bustype = BUS_PCI; input_dev->id.version = 1; @@ -218,7 +217,6 @@ static int msp430_ir_init(struct budget_ci *budget_ci) input_dev->dev = &saa->pci->dev; #endif #endif -#endif /* Select keymap and address */ switch (budget_ci->budget.dev->pci->subsystem_device) { diff --git a/linux/drivers/media/dvb/ttpci/budget-core.c b/linux/drivers/media/dvb/ttpci/budget-core.c index 18cac4b12..6f4ddb643 100644 --- a/linux/drivers/media/dvb/ttpci/budget-core.c +++ b/linux/drivers/media/dvb/ttpci/budget-core.c @@ -497,11 +497,7 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, if (bi->type != BUDGET_FS_ACTIVY) saa7146_write(dev, GPIO_CTRL, 0x500000); /* GPIO 3 = 1 */ -#ifdef I2C_ADAP_CLASS_TV_DIGITAL - budget->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL; -#else budget->i2c_adap.class = I2C_CLASS_TV_DIGITAL; -#endif strlcpy(budget->i2c_adap.name, budget->card->name, sizeof(budget->i2c_adap.name)); diff --git a/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index df7add8a9..fa84a6b49 100644 --- a/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c @@ -1698,11 +1698,7 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i i2c_set_adapdata(&ttusb->i2c_adap, ttusb); -#ifdef I2C_ADAP_CLASS_TV_DIGITAL - ttusb->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL; -#else ttusb->i2c_adap.class = I2C_CLASS_TV_DIGITAL; -#endif ttusb->i2c_adap.algo = &ttusb_dec_algo; ttusb->i2c_adap.algo_data = NULL; ttusb->i2c_adap.dev.parent = &udev->dev; diff --git a/linux/drivers/media/video/au0828/au0828-dvb.c b/linux/drivers/media/video/au0828/au0828-dvb.c index 709a703fe..0a835354f 100644 --- a/linux/drivers/media/video/au0828/au0828-dvb.c +++ b/linux/drivers/media/video/au0828/au0828-dvb.c @@ -224,17 +224,10 @@ static int dvb_register(struct au0828_dev *dev) "(errno = %d)\n", DRIVER_NAME, result); goto fail_adapter; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) dvb->adapter.priv = dev; /* register frontend */ result = dvb_register_frontend(&dvb->adapter, dvb->frontend); -#else - dvb->adapter->priv = dev; - - /* register frontend */ - result = dvb_register_frontend(dvb->adapter, dvb->frontend); -#endif if (result < 0) { printk(KERN_ERR "%s: dvb_register_frontend failed " "(errno = %d)\n", DRIVER_NAME, result); @@ -260,11 +253,7 @@ static int dvb_register(struct au0828_dev *dev) dvb->dmxdev.filternum = 256; dvb->dmxdev.demux = &dvb->demux.dmx; dvb->dmxdev.capabilities = 0; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); -#else - result = dvb_dmxdev_init(&dvb->dmxdev, dvb->adapter); -#endif if (result < 0) { printk(KERN_ERR "%s: dvb_dmxdev_init failed (errno = %d)\n", DRIVER_NAME, result); @@ -295,11 +284,7 @@ static int dvb_register(struct au0828_dev *dev) } /* register network adapter */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); -#else - dvb_net_init(dvb->adapter, &dvb->net, &dvb->demux.dmx); -#endif return 0; fail_fe_conn: @@ -314,11 +299,7 @@ fail_dmx: dvb_unregister_frontend(dvb->frontend); fail_frontend: dvb_frontend_detach(dvb->frontend); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) dvb_unregister_adapter(&dvb->adapter); -#else - dvb_unregister_adapter(dvb->adapter); -#endif fail_adapter: return result; } @@ -339,11 +320,7 @@ void au0828_dvb_unregister(struct au0828_dev *dev) dvb_dmx_release(&dvb->demux); dvb_unregister_frontend(dvb->frontend); dvb_frontend_detach(dvb->frontend); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) dvb_unregister_adapter(&dvb->adapter); -#else - dvb_unregister_adapter(dvb->adapter); -#endif } /* All the DVB attach calls go here, this function get's modified diff --git a/linux/drivers/media/video/au0828/au0828-i2c.c b/linux/drivers/media/video/au0828/au0828-i2c.c index b40a086e4..32858dceb 100644 --- a/linux/drivers/media/video/au0828/au0828-i2c.c +++ b/linux/drivers/media/video/au0828/au0828-i2c.c @@ -307,9 +307,7 @@ static struct i2c_algorithm au0828_i2c_algo_template = { static struct i2c_adapter au0828_i2c_adap_template = { .name = DRIVER_NAME, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) .owner = THIS_MODULE, -#endif .id = I2C_HW_B_AU0828, .algo = &au0828_i2c_algo_template, .class = I2C_CLASS_TV_ANALOG, diff --git a/linux/drivers/media/video/bt8xx/bt832.c b/linux/drivers/media/video/bt8xx/bt832.c index 4eefaba8f..e860f7725 100644 --- a/linux/drivers/media/video/bt8xx/bt832.c +++ b/linux/drivers/media/video/bt8xx/bt832.c @@ -33,9 +33,6 @@ #include <linux/slab.h> #include <media/v4l2-common.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include "i2c-compat.h" -#endif #include "bttv.h" #include "bt832.h" @@ -44,17 +41,10 @@ MODULE_LICENSE("GPL"); /* Addresses to scan */ static unsigned short normal_i2c[] = { I2C_ADDR_BT832_ALT1>>1, I2C_ADDR_BT832_ALT2>>1, I2C_CLIENT_END }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif I2C_CLIENT_INSMOD; int debug; /* debug output */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) module_param(debug, int, 0644); -#else -MODULE_PARM(debug, "i"); -#endif /* ---------------------------------------------------------------------- */ @@ -187,12 +177,7 @@ int bt832_init(struct i2c_client *i2c_client_s) -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) static int bt832_attach(struct i2c_adapter *adap, int addr, int kind) -#else -static int bt832_attach(struct i2c_adapter *adap, int addr, - unsigned short flags, int kind) -#endif { struct bt832 *t; @@ -207,10 +192,6 @@ static int bt832_attach(struct i2c_adapter *adap, int addr, v4l_info(&t->client,"chip found @ 0x%x\n", addr<<1); - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - MOD_INC_USE_COUNT; -#endif if(! bt832_init(&t->client)) { bt832_detach(&t->client); return -1; @@ -221,13 +202,8 @@ static int bt832_attach(struct i2c_adapter *adap, int addr, static int bt832_probe(struct i2c_adapter *adap) { -#ifdef I2C_CLASS_TV_ANALOG if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, bt832_attach); -#else - if (adap->id == I2C_HW_B_BT848) - return i2c_probe(adap, &addr_data, bt832_attach); -#endif return 0; } @@ -238,9 +214,6 @@ static int bt832_detach(struct i2c_client *client) v4l_info(&t->client,"dettach\n"); i2c_detach_client(client); kfree(t); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - MOD_DEC_USE_COUNT; -#endif return 0; } @@ -277,7 +250,7 @@ bt832_command(struct i2c_client *client, unsigned int cmd, void *arg) /* ----------------------------------------------------------------------- */ static struct i2c_driver driver = { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))&&(LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)) +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) .owner = THIS_MODULE, #endif #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) diff --git a/linux/drivers/media/video/bt8xx/bttv-cards.c b/linux/drivers/media/video/bt8xx/bttv-cards.c index 0e6771643..4d283be22 100644 --- a/linux/drivers/media/video/bt8xx/bttv-cards.c +++ b/linux/drivers/media/video/bt8xx/bttv-cards.c @@ -115,31 +115,12 @@ module_param(gpiomask, int, 0444); module_param(audioall, int, 0444); module_param(autoload, int, 0444); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -MODULE_PARM(card,"1-" __stringify(BTTV_MAX) "i"); -MODULE_PARM(pll,"1-" __stringify(BTTV_MAX) "i"); -MODULE_PARM(tuner,"1-" __stringify(BTTV_MAX) "i"); -MODULE_PARM(svhs,"1-" __stringify(BTTV_MAX) "i"); -MODULE_PARM(remote,"1-" __stringify(BTTV_MAX) "i"); -MODULE_PARM(audiomux,"1-" __stringify(BTTV_MAX) "i"); -#else -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) -static int dummy; -module_param_array(card, int, dummy, 0444); -module_param_array(pll, int, dummy, 0444); -module_param_array(tuner, int, dummy, 0444); -module_param_array(svhs, int, dummy, 0444); -module_param_array(remote, int, dummy, 0444); -module_param_array(audiomux, int, dummy, 0444); -#else module_param_array(card, int, NULL, 0444); module_param_array(pll, int, NULL, 0444); module_param_array(tuner, int, NULL, 0444); module_param_array(svhs, int, NULL, 0444); module_param_array(remote, int, NULL, 0444); module_param_array(audiomux, int, NULL, 0444); -#endif -#endif MODULE_PARM_DESC(triton1,"set ETBF pci config bit " "[enable bug compatibility for triton1 + others]"); @@ -3870,11 +3851,7 @@ static int __devinit pvr_boot(struct bttv *btv) const struct firmware *fw_entry; int rc; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) rc = request_firmware(&fw_entry, "hcwamc.rbf", &btv->c.pci->dev); -#else - rc = request_firmware(&fw_entry, "hcwamc.rbf", pci_name(btv->c.pci)); -#endif if (rc != 0) { printk(KERN_WARNING "bttv%d: no altera firmware [via hotplug]\n", btv->c.nr); diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c index 15f10b88a..36efd08f8 100644 --- a/linux/drivers/media/video/bt8xx/bttv-driver.c +++ b/linux/drivers/media/video/bt8xx/bttv-driver.c @@ -48,9 +48,7 @@ #include <media/tvaudio.h> #include <media/msp3400.h> -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) #include <linux/dma-mapping.h> -#endif #include <asm/io.h> #include <asm/byteorder.h> @@ -132,16 +130,7 @@ module_param(uv_ratio, int, 0444); module_param(full_luma_range, int, 0444); module_param(coring, int, 0444); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -MODULE_PARM(radio,"1-" __stringify(BTTV_MAX) "i"); -#else -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) -static int dummy; -module_param_array(radio, int, dummy, 0444); -#else module_param_array(radio, int, NULL, 0444); -#endif -#endif MODULE_PARM_DESC(radio,"The TV card supports radio, default is 0 (no)"); MODULE_PARM_DESC(bigendian,"byte order of the framebuffer, default is native endian"); @@ -171,20 +160,14 @@ MODULE_LICENSE("GPL"); /* ----------------------------------------------------------------------- */ /* sysfs */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13) static ssize_t show_card(struct device *cd, struct device_attribute *attr, char *buf) -#else -static ssize_t show_card(struct class_device *cd, char *buf) -#endif { struct video_device *vfd = container_of(cd, struct video_device, class_dev); struct bttv *btv = dev_get_drvdata(vfd->dev); return sprintf(buf, "%d\n", btv ? btv->c.type : UNSET); } static DEVICE_ATTR(card, S_IRUGO, show_card, NULL); -#endif /* ----------------------------------------------------------------------- */ /* dvb auto-load setup */ @@ -198,9 +181,6 @@ static void request_module_async(struct work_struct *work) request_module("dvb-bt8xx"); } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#define request_modules(dev) -#else static void request_modules(struct bttv *dev) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) @@ -210,7 +190,6 @@ static void request_modules(struct bttv *dev) #endif schedule_work(&dev->request_module_wk); } -#endif #else #define request_modules(dev) #endif /* CONFIG_MODULES */ @@ -3391,9 +3370,7 @@ static const struct file_operations bttv_fops = .open = bttv_open, .release = bttv_release, .ioctl = video_ioctl2, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) .compat_ioctl = v4l_compat_ioctl32, -#endif .llseek = no_llseek, .read = bttv_read, .mmap = bttv_mmap, @@ -3672,9 +3649,7 @@ static const struct file_operations radio_fops = .open = radio_open, .read = radio_read, .release = radio_release, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) .compat_ioctl = v4l_compat_ioctl32, -#endif .ioctl = video_ioctl2, .llseek = no_llseek, .poll = radio_poll, @@ -4115,10 +4090,8 @@ static irqreturn_t bttv_irq(int irq, void *dev_id) btv=(struct bttv *)dev_id; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) if (btv->custom_irq) handled = btv->custom_irq(btv); -#endif count=0; while (1) { @@ -4156,9 +4129,7 @@ static irqreturn_t bttv_irq(int irq, void *dev_id) if ((astat & BT848_INT_GPINT) && btv->remote) { wake_up(&btv->gpioq); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) bttv_input_irq(btv); -#endif } if (astat & BT848_INT_I2CDONE) { @@ -4238,10 +4209,8 @@ static struct video_device *vdev_init(struct bttv *btv, return NULL; *vfd = *template; vfd->minor = -1; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) vfd->dev = &btv->c.pci->dev; vfd->release = video_device_release; -#endif vfd->type = type; vfd->debug = bttv_debug; snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)", @@ -4394,11 +4363,7 @@ static int __devinit bttv_probe(struct pci_dev *dev, btv->c.nr); return -EIO; } -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,7) - if (pci_set_dma_mask(dev, 0xffffffff)) { -#else if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) { -#endif printk(KERN_WARNING "bttv%d: No suitable DMA available.\n", btv->c.nr); return -EIO; @@ -4509,13 +4474,11 @@ static int __devinit bttv_probe(struct pci_dev *dev, disclaim_video_lines(btv); } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) /* add subdevices and autoload dvb-bt8xx if needed */ if (bttv_tvcards[btv->c.type].has_dvb) { bttv_sub_add_device(&btv->c, "dvb"); request_modules(btv); } -#endif bttv_input_init(btv); @@ -4554,9 +4517,7 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev) btv->shutdown=1; wake_up(&btv->gpioq); bttv_input_fini(btv); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) bttv_sub_del_devices(&btv->c); -#endif /* unregister i2c_bus + input */ fini_bttv_i2c(btv); @@ -4609,11 +4570,7 @@ static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state) btv->state.gpio_data = gpio_read(); /* save pci state */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) - pci_save_state(pci_dev, btv->state.pci_cfg); -#else pci_save_state(pci_dev); -#endif if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) { pci_disable_device(pci_dev); btv->state.disabled = 1; @@ -4648,11 +4605,7 @@ static int bttv_resume(struct pci_dev *pci_dev) return err; } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) - pci_restore_state(pci_dev, btv->state.pci_cfg); -#else pci_restore_state(pci_dev); -#endif /* restore bt878 state */ bttv_reinit_bt848(btv); @@ -4722,13 +4675,11 @@ static int __init bttv_init_module(void) bttv_check_chipset(); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ret = bus_register(&bttv_sub_bus_type); if (ret < 0) { printk(KERN_WARNING "bttv: bus_register error: %d\n", ret); return ret; } -#endif ret = pci_register_driver(&bttv_pci_driver); if (ret < 0) bus_unregister(&bttv_sub_bus_type); @@ -4739,9 +4690,7 @@ static int __init bttv_init_module(void) static void __exit bttv_cleanup_module(void) { pci_unregister_driver(&bttv_pci_driver); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) bus_unregister(&bttv_sub_bus_type); -#endif } module_init(bttv_init_module); diff --git a/linux/drivers/media/video/bt8xx/bttv-i2c.c b/linux/drivers/media/video/bt8xx/bttv-i2c.c index 746b9dd77..4f48dfb26 100644 --- a/linux/drivers/media/video/bt8xx/bttv-i2c.c +++ b/linux/drivers/media/video/bt8xx/bttv-i2c.c @@ -33,9 +33,7 @@ #include "bttvp.h" #include <media/v4l2-common.h> -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) #include <linux/jiffies.h> -#endif #include <asm/io.h> static int attach_inform(struct i2c_client *client); @@ -423,14 +421,10 @@ int __devinit init_bttv_i2c(struct bttv *btv) btv->c.i2c_adap.algo_data = &btv->i2c_algo; } btv->c.i2c_adap.owner = THIS_MODULE; -#ifdef I2C_CLASS_TV_ANALOG btv->c.i2c_adap.class = I2C_CLASS_TV_ANALOG; -#endif btv->c.i2c_adap.client_register = attach_inform; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,66) btv->c.i2c_adap.dev.parent = &btv->c.pci->dev; -#endif snprintf(btv->c.i2c_adap.name, sizeof(btv->c.i2c_adap.name), "bt%d #%d [%s]", btv->id, btv->c.nr, btv->use_i2c_hw ? "hw" : "sw"); @@ -438,12 +432,10 @@ int __devinit init_bttv_i2c(struct bttv *btv) i2c_set_adapdata(&btv->c.i2c_adap, btv); btv->i2c_client.adapter = &btv->c.i2c_adap; -#ifdef I2C_CLASS_TV_ANALOG if (bttv_tvcards[btv->c.type].no_video) btv->c.i2c_adap.class &= ~I2C_CLASS_TV_ANALOG; if (bttv_tvcards[btv->c.type].has_dvb) btv->c.i2c_adap.class |= I2C_CLASS_TV_DIGITAL; -#endif if (btv->use_i2c_hw) { btv->i2c_rc = i2c_add_adapter(&btv->c.i2c_adap); diff --git a/linux/drivers/media/video/bt8xx/bttv-input.c b/linux/drivers/media/video/bt8xx/bttv-input.c index f82213990..ada104826 100644 --- a/linux/drivers/media/video/bt8xx/bttv-input.c +++ b/linux/drivers/media/video/bt8xx/bttv-input.c @@ -313,7 +313,6 @@ int bttv_input_init(struct bttv *btv) ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); input_dev->name = ir->name; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) input_dev->phys = ir->phys; input_dev->id.bustype = BUS_PCI; input_dev->id.version = 1; @@ -333,7 +332,6 @@ int bttv_input_init(struct bttv *btv) input_dev->dev = &btv->c.pci->dev; #endif #endif -#endif btv->remote = ir; bttv_ir_start(btv, ir); diff --git a/linux/drivers/media/video/bt8xx/bttv.h b/linux/drivers/media/video/bt8xx/bttv.h index 4c73aacdb..dab61e62e 100644 --- a/linux/drivers/media/video/bt8xx/bttv.h +++ b/linux/drivers/media/video/bt8xx/bttv.h @@ -302,8 +302,6 @@ extern int bttv_write_gpio(unsigned int card, /* ---------------------------------------------------------- */ /* sysfs/driver-moded based gpio access interface */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - struct bttv_sub_device { struct device dev; struct bttv_core *core; @@ -335,14 +333,6 @@ void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits); #define gpio_write(value) bttv_gpio_write(&btv->c, value) #define gpio_bits(mask,bits) bttv_gpio_bits(&btv->c, mask, bits) -#else - -#define gpio_inout(mask,bits) btaor((mask)&(bits),~(mask),BT848_GPIO_OUT_EN) -#define gpio_read() btread(BT848_GPIO_DATA) -#define gpio_write(value) btwrite((value),BT848_GPIO_DATA) -#define gpio_bits(mask,bits) btaor((mask)&(bits),~(mask),BT848_GPIO_DATA) - -#endif /* ---------------------------------------------------------- */ /* i2c */ diff --git a/linux/drivers/media/video/bt8xx/bttvp.h b/linux/drivers/media/video/bt8xx/bttvp.h index 9fd8eeddf..c3d1703ac 100644 --- a/linux/drivers/media/video/bt8xx/bttvp.h +++ b/linux/drivers/media/video/bt8xx/bttvp.h @@ -42,13 +42,7 @@ #include <asm/io.h> #include "compat.h" #include <media/v4l2-common.h> - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include "i2c-compat.h" -#define strlcpy(dest,src,len) strncpy(dest,src,(len)-1) -#else #include <linux/device.h> -#endif #include <media/videobuf-dma-sg.h> #include <media/tveeprom.h> #include <media/ir-common.h> @@ -272,14 +266,10 @@ extern struct videobuf_queue_ops bttv_vbi_qops; /* ---------------------------------------------------------- */ /* bttv-gpio.c */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - extern struct bus_type bttv_sub_bus_type; int bttv_sub_add_device(struct bttv_core *core, char *name); int bttv_sub_del_devices(struct bttv_core *core); -#endif - /* ---------------------------------------------------------- */ /* bttv-driver.c */ @@ -318,9 +308,6 @@ struct bttv_input { }; struct bttv_suspend_state { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) - u32 pci_cfg[64 / sizeof(u32)]; -#endif u32 gpio_enable; u32 gpio_data; int disabled; diff --git a/linux/drivers/media/video/compat_ioctl32.c b/linux/drivers/media/video/compat_ioctl32.c index 6b405e75c..017c2a8d4 100644 --- a/linux/drivers/media/video/compat_ioctl32.c +++ b/linux/drivers/media/video/compat_ioctl32.c @@ -12,7 +12,6 @@ * ioctls. */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) #include <linux/compat.h> #include <linux/videodev.h> #include <linux/videodev2.h> @@ -996,4 +995,3 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) EXPORT_SYMBOL_GPL(v4l_compat_ioctl32); MODULE_LICENSE("GPL"); -#endif diff --git a/linux/drivers/media/video/cs5345.c b/linux/drivers/media/video/cs5345.c index d0bdc009d..e2f0b0278 100644 --- a/linux/drivers/media/video/cs5345.c +++ b/linux/drivers/media/video/cs5345.c @@ -34,21 +34,13 @@ MODULE_LICENSE("GPL"); static int debug; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) module_param(debug, bool, 0644); -#else -MODULE_PARM(debug, "i"); -#endif MODULE_PARM_DESC(debug, "Debugging messages\n\t\t\t0=Off (default), 1=On"); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) static unsigned short normal_i2c[] = { 0x98 >> 1, I2C_CLIENT_END }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif - I2C_CLIENT_INSMOD; #endif @@ -191,7 +183,3 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .id_table = cs5345_id, #endif }; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -EXPORT_NO_SYMBOLS; -#endif diff --git a/linux/drivers/media/video/cs53l32a.c b/linux/drivers/media/video/cs53l32a.c index 7c0761e21..bef0950e5 100644 --- a/linux/drivers/media/video/cs53l32a.c +++ b/linux/drivers/media/video/cs53l32a.c @@ -30,10 +30,6 @@ #include <media/v4l2-common.h> #include <media/v4l2-chip-ident.h> #include <media/v4l2-i2c-drv-legacy.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -#include "i2c-compat.h" -#include <linux/slab.h> -#endif #include "compat.h" MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC"); @@ -42,20 +38,12 @@ MODULE_LICENSE("GPL"); static int debug; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) module_param(debug, bool, 0644); -#else -MODULE_PARM(debug, "i"); -#endif MODULE_PARM_DESC(debug, "Debugging messages\n\t\t\t0=Off (default), 1=On"); static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif - I2C_CLIENT_INSMOD; /* ----------------------------------------------------------------------- */ @@ -209,7 +197,3 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .id_table = cs53l32a_id, #endif }; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -EXPORT_NO_SYMBOLS; -#endif diff --git a/linux/drivers/media/video/cx18/cx18-cards.c b/linux/drivers/media/video/cx18/cx18-cards.c index bb45bcf68..0caae1a5e 100644 --- a/linux/drivers/media/video/cx18/cx18-cards.c +++ b/linux/drivers/media/video/cx18/cx18-cards.c @@ -196,7 +196,7 @@ static const struct cx18_card_pci_info cx18_pci_mpc718[] = { static const struct cx18_card cx18_card_mpc718 = { .type = CX18_CARD_YUAN_MPC718, .name = "Yuan MPC718", - .comment = "Some Composite and S-Video inputs are currently working.\n", + .comment = "Analog video capture works; some audio line in may not.\n", .v4l2_capabilities = CX18_CAP_ENCODER, .hw_audio_ctrl = CX18_HW_CX23418, .hw_all = CX18_HW_TUNER, @@ -229,7 +229,7 @@ static const struct cx18_card cx18_card_mpc718 = { .tune_lane = 0, .initial_emrs = 2, }, - .xceive_pin = 15, + .xceive_pin = 0, .pci_list = cx18_pci_mpc718, .i2c = &cx18_i2c_std, }; diff --git a/linux/drivers/media/video/cx18/cx18-i2c.c b/linux/drivers/media/video/cx18/cx18-i2c.c index 5b8550e0e..64a259405 100644 --- a/linux/drivers/media/video/cx18/cx18-i2c.c +++ b/linux/drivers/media/video/cx18/cx18-i2c.c @@ -39,10 +39,6 @@ #define GETSCL_BIT 0x0004 #define GETSDL_BIT 0x0008 -#ifndef I2C_ADAP_CLASS_TV_ANALOG -#define I2C_ADAP_CLASS_TV_ANALOG I2C_CLASS_TV_ANALOG -#endif - #define CX18_CS5345_I2C_ADDR 0x4c /* This array should match the CX18_HW_ defines */ @@ -234,9 +230,7 @@ static struct i2c_adapter cx18_i2c_adap_template = { .client_unregister = detach_inform, .owner = THIS_MODULE, #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) -#ifdef I2C_ADAP_CLASS_TV_ANALOG - .class = I2C_ADAP_CLASS_TV_ANALOG, -#endif + .class = I2C_CLASS_TV_ANALOG, #endif }; @@ -439,6 +433,7 @@ int init_cx18_i2c(struct cx18 *cx) write_reg_sync(0x00c000c0, 0xc7001c); mdelay(10); write_reg_sync(0x00c00000, 0xc7001c); + mdelay(10); write_reg_sync(0x00c00000, 0xc730c8); /* Set to edge-triggered intrs. */ write_reg_sync(0x00c00000, 0xc730c4); /* Clear any stale intrs */ diff --git a/linux/drivers/media/video/cx18/cx18-streams.c b/linux/drivers/media/video/cx18/cx18-streams.c index deacdb836..df99070e6 100644 --- a/linux/drivers/media/video/cx18/cx18-streams.c +++ b/linux/drivers/media/video/cx18/cx18-streams.c @@ -41,9 +41,7 @@ static struct file_operations cx18_v4l2_enc_fops = { .open = cx18_v4l2_open, /* FIXME change to video_ioctl2 if serialization lock can be removed */ .ioctl = cx18_v4l2_ioctl, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) .compat_ioctl = v4l_compat_ioctl32, -#endif .release = cx18_v4l2_close, .poll = cx18_v4l2_enc_poll, }; diff --git a/linux/drivers/media/video/cx2341x.c b/linux/drivers/media/video/cx2341x.c index 76b2f8c62..3f2191162 100644 --- a/linux/drivers/media/video/cx2341x.c +++ b/linux/drivers/media/video/cx2341x.c @@ -25,9 +25,6 @@ #include <linux/init.h> #include <linux/types.h> #include <linux/videodev2.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -#include <linux/slab.h> -#endif #include <media/tuner.h> #include <media/cx2341x.h> diff --git a/linux/drivers/media/video/cx23885/cx23885-i2c.c b/linux/drivers/media/video/cx23885/cx23885-i2c.c index ba8e27ca9..f0ee47256 100644 --- a/linux/drivers/media/video/cx23885/cx23885-i2c.c +++ b/linux/drivers/media/video/cx23885/cx23885-i2c.c @@ -359,9 +359,7 @@ static struct i2c_algorithm cx23885_i2c_algo_template = { static struct i2c_adapter cx23885_i2c_adap_template = { .name = "cx23885", -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) .owner = THIS_MODULE, -#endif .id = I2C_HW_B_CX23885, .algo = &cx23885_i2c_algo_template, .class = I2C_CLASS_TV_ANALOG, diff --git a/linux/drivers/media/video/cx23885/cx23885-video.c b/linux/drivers/media/video/cx23885/cx23885-video.c index fdbcd53ab..6d0345935 100644 --- a/linux/drivers/media/video/cx23885/cx23885-video.c +++ b/linux/drivers/media/video/cx23885/cx23885-video.c @@ -29,9 +29,7 @@ #include <linux/interrupt.h> #include <linux/delay.h> #include "compat.h" -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0) #include <linux/kthread.h> -#endif #include <asm/div64.h> #include "cx23885.h" @@ -52,22 +50,9 @@ static unsigned int video_nr[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET }; static unsigned int vbi_nr[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET }; static unsigned int radio_nr[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -MODULE_PARM(video_nr, "1-" __stringify(CX23885_MAXBOARDS) "i"); -MODULE_PARM(vbi_nr, "1-" __stringify(CX23885_MAXBOARDS) "i"); -MODULE_PARM(radio_nr, "1-" __stringify(CX23885_MAXBOARDS) "i"); -#else -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10) -static unsigned int dummy; -module_param_array(video_nr, int, dummy, 0444); -module_param_array(vbi_nr, int, dummy, 0444); -module_param_array(radio_nr, int, dummy, 0444); -#else module_param_array(video_nr, int, NULL, 0444); module_param_array(vbi_nr, int, NULL, 0444); module_param_array(radio_nr, int, NULL, 0444); -#endif -#endif MODULE_PARM_DESC(video_nr, "video device numbers"); MODULE_PARM_DESC(vbi_nr, "vbi device numbers"); @@ -376,10 +361,8 @@ struct video_device *cx23885_vdev_init(struct cx23885_dev *dev, return NULL; *vfd = *template; vfd->minor = -1; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0) vfd->dev = &pci->dev; vfd->release = video_device_release; -#endif snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type, cx23885_boards[dev->board].name); return vfd; @@ -1654,9 +1637,7 @@ static const struct file_operations video_fops = { .poll = video_poll, .mmap = video_mmap, .ioctl = video_ioctl2, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) .compat_ioctl = v4l_compat_ioctl32, -#endif .llseek = no_llseek, }; @@ -1707,9 +1688,7 @@ static const struct file_operations radio_fops = { .open = video_open, .release = video_release, .ioctl = video_ioctl2, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) .compat_ioctl = v4l_compat_ioctl32, -#endif .llseek = no_llseek, }; diff --git a/linux/drivers/media/video/cx25840/cx25840-audio.c b/linux/drivers/media/video/cx25840/cx25840-audio.c index eda48b596..8e134312c 100644 --- a/linux/drivers/media/video/cx25840/cx25840-audio.c +++ b/linux/drivers/media/video/cx25840/cx25840-audio.c @@ -21,9 +21,6 @@ #include <media/v4l2-common.h> #include <media/cx25840.h> #include "compat.h" -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include "i2c-compat.h" -#endif #include "cx25840-core.h" diff --git a/linux/drivers/media/video/cx25840/cx25840-core.c b/linux/drivers/media/video/cx25840/cx25840-core.c index ca5cc0f51..a43ed390a 100644 --- a/linux/drivers/media/video/cx25840/cx25840-core.c +++ b/linux/drivers/media/video/cx25840/cx25840-core.c @@ -42,9 +42,6 @@ #include <media/v4l2-i2c-drv-legacy.h> #include <media/cx25840.h> #include "compat.h" -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include "i2c-compat.h" -#endif #include "cx25840-core.h" @@ -54,17 +51,9 @@ MODULE_LICENSE("GPL"); static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif - int cx25840_debug; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) module_param_named(debug,cx25840_debug, int, 0644); -#else -MODULE_PARM(cx25840_debug, "i"); -#endif MODULE_PARM_DESC(debug, "Debugging messages [0=Off (default) 1=On]"); diff --git a/linux/drivers/media/video/cx25840/cx25840-firmware.c b/linux/drivers/media/video/cx25840/cx25840-firmware.c index d283ef2d1..95b84ce21 100644 --- a/linux/drivers/media/video/cx25840/cx25840-firmware.c +++ b/linux/drivers/media/video/cx25840/cx25840-firmware.c @@ -38,19 +38,11 @@ */ #define FWSEND 48 -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) #define FWDEV(x) &((x)->dev) -#else -#define FWDEV(x) (x)->name -#endif static char *firmware = FWFILE; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) module_param(firmware, charp, 0444); -#else -MODULE_PARM(firmware, "s"); -#endif MODULE_PARM_DESC(firmware, "Firmware image [default: " FWFILE "]"); diff --git a/linux/drivers/media/video/cx88/cx88-alsa.c b/linux/drivers/media/video/cx88/cx88-alsa.c index a8e985b6f..c675cbeae 100644 --- a/linux/drivers/media/video/cx88/cx88-alsa.c +++ b/linux/drivers/media/video/cx88/cx88-alsa.c @@ -98,10 +98,6 @@ struct cx88_audio_dev { typedef struct cx88_audio_dev snd_cx88_card_t; -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,8) -#define chip_t snd_cx88_card_t -#endif - #ifdef COMPAT_SND_CTL_BOOLEAN_MONO static int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) @@ -122,19 +118,10 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1}; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) -static unsigned int dummy; -module_param_array(enable, bool, dummy, 0444); -#else module_param_array(enable, bool, NULL, 0444); -#endif MODULE_PARM_DESC(enable, "Enable cx88x soundcard. default enabled."); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) -module_param_array(index, int, dummy, 0444); -#else module_param_array(index, int, NULL, 0444); -#endif MODULE_PARM_DESC(index, "Index value for cx88x capture interface(s)."); diff --git a/linux/drivers/media/video/cx88/cx88-blackbird.c b/linux/drivers/media/video/cx88/cx88-blackbird.c index a642d3dc8..83638557d 100644 --- a/linux/drivers/media/video/cx88/cx88-blackbird.c +++ b/linux/drivers/media/video/cx88/cx88-blackbird.c @@ -30,9 +30,7 @@ #include <linux/init.h> #include <linux/fs.h> #include <linux/delay.h> -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) #include <linux/device.h> -#endif #include <linux/firmware.h> #include <media/v4l2-common.h> #include <media/cx2341x.h> @@ -444,13 +442,8 @@ static int blackbird_load_firmware(struct cx8802_dev *dev) if (retval < 0) dprintk(0, "Error with register_write\n"); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) retval = request_firmware(&firmware, CX2341X_FIRM_ENC_FILENAME, &dev->pci->dev); -#else - retval = request_firmware(&firmware, CX2341X_FIRM_ENC_FILENAME, - pci_name(dev->pci)); -#endif if (retval != 0) { diff --git a/linux/drivers/media/video/cx88/cx88-cards.c b/linux/drivers/media/video/cx88/cx88-cards.c index 1fb39e08e..9329dbf6a 100644 --- a/linux/drivers/media/video/cx88/cx88-cards.c +++ b/linux/drivers/media/video/cx88/cx88-cards.c @@ -33,22 +33,9 @@ static unsigned int tuner[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; static unsigned int radio[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; static unsigned int card[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -MODULE_PARM(tuner,"1-" __stringify(CX88_MAXBOARDS) "i"); -MODULE_PARM(radiox,"1-" __stringify(CX88_MAXBOARDS) "i"); -MODULE_PARM(card,"1-" __stringify(CX88_MAXBOARDS) "i"); -#else -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) -static int dummy; -module_param_array(tuner, int, dummy, 0444); -module_param_array(radio, int, dummy, 0444); -module_param_array(card, int, dummy, 0444); -#else module_param_array(tuner, int, NULL, 0444); module_param_array(radio, int, NULL, 0444); module_param_array(card, int, NULL, 0444); -#endif -#endif MODULE_PARM_DESC(tuner,"tuner type"); MODULE_PARM_DESC(radio,"radio tuner type"); diff --git a/linux/drivers/media/video/cx88/cx88-core.c b/linux/drivers/media/video/cx88/cx88-core.c index 5d6265c1d..6efb1c61a 100644 --- a/linux/drivers/media/video/cx88/cx88-core.c +++ b/linux/drivers/media/video/cx88/cx88-core.c @@ -1037,10 +1037,8 @@ struct video_device *cx88_vdev_init(struct cx88_core *core, return NULL; *vfd = *template; vfd->minor = -1; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) vfd->dev = &pci->dev; vfd->release = video_device_release; -#endif snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", core->name, type, core->board.name); return vfd; diff --git a/linux/drivers/media/video/cx88/cx88-i2c.c b/linux/drivers/media/video/cx88/cx88-i2c.c index 800ea0d64..df615f19a 100644 --- a/linux/drivers/media/video/cx88/cx88-i2c.c +++ b/linux/drivers/media/video/cx88/cx88-i2c.c @@ -34,9 +34,6 @@ #include "cx88.h" #include <media/v4l2-common.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include "i2c-compat.h" -#endif static unsigned int i2c_debug; module_param(i2c_debug, int, 0644); @@ -187,22 +184,14 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) memcpy(&core->i2c_algo, &cx8800_i2c_algo_template, sizeof(core->i2c_algo)); -#ifdef I2C_CLASS_TV_ANALOG if (core->board.tuner_type != TUNER_ABSENT) core->i2c_adap.class |= I2C_CLASS_TV_ANALOG; -#endif -#ifdef I2C_CLASS_TV_DIGITAL if (core->board.mpeg & CX88_MPEG_DVB) core->i2c_adap.class |= I2C_CLASS_TV_DIGITAL; -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,66) core->i2c_adap.dev.parent = &pci->dev; -#endif strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name)); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) core->i2c_adap.owner = THIS_MODULE; -#endif core->i2c_adap.id = I2C_HW_B_CX2388x; core->i2c_adap.client_register = attach_inform; core->i2c_adap.client_unregister = detach_inform; diff --git a/linux/drivers/media/video/cx88/cx88-input.c b/linux/drivers/media/video/cx88/cx88-input.c index e334bd20a..4796e3ba1 100644 --- a/linux/drivers/media/video/cx88/cx88-input.c +++ b/linux/drivers/media/video/cx88/cx88-input.c @@ -349,7 +349,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); input_dev->name = ir->name; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) input_dev->phys = ir->phys; input_dev->id.bustype = BUS_PCI; input_dev->id.version = 1; @@ -369,7 +368,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) input_dev->dev = &pci->dev; #endif #endif -#endif /* record handles to ourself */ ir->core = core; core->ir = ir; @@ -500,11 +498,9 @@ void cx88_ir_irq(struct cx88_core *core) /* ---------------------------------------------------------------------- */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) MODULE_AUTHOR("Gerd Knorr, Pavel Machek, Chris Pascoe"); MODULE_DESCRIPTION("input driver for cx88 GPIO-based IR remote controls"); MODULE_LICENSE("GPL"); -#endif /* * Local variables: * c-basic-offset: 8 diff --git a/linux/drivers/media/video/cx88/cx88-mpeg.c b/linux/drivers/media/video/cx88/cx88-mpeg.c index c8dba3dfa..4af6604ec 100644 --- a/linux/drivers/media/video/cx88/cx88-mpeg.c +++ b/linux/drivers/media/video/cx88/cx88-mpeg.c @@ -24,9 +24,7 @@ #include <linux/module.h> #include <linux/init.h> -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) #include <linux/device.h> -#endif #include <linux/dma-mapping.h> #include <linux/interrupt.h> #include <asm/delay.h> @@ -36,13 +34,9 @@ /* ------------------------------------------------------------------ */ MODULE_DESCRIPTION("mpeg driver for cx2388x based TV cards"); -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>"); MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); -#else -MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>,Chris Pascoe <c.pascoe@itee.uq.edu.au>,Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); -#endif MODULE_LICENSE("GPL"); static unsigned int debug; @@ -72,9 +66,6 @@ static void request_module_async(struct work_struct *work) request_module("cx88-blackbird"); } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#define request_modules(dev) -#else static void request_modules(struct cx8802_dev *dev) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) @@ -84,7 +75,6 @@ static void request_modules(struct cx8802_dev *dev) #endif schedule_work(&dev->request_module_wk); } -#endif #else #define request_modules(dev) #endif /* CONFIG_MODULES */ @@ -576,11 +566,7 @@ static int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state) cx88_shutdown(dev->core); #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) - pci_save_state(pci_dev, dev->state.pci_cfg); -#else pci_save_state(pci_dev); -#endif if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) { pci_disable_device(pci_dev); dev->state.disabled = 1; @@ -612,11 +598,7 @@ static int cx8802_resume_common(struct pci_dev *pci_dev) return err; } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) - pci_restore_state(pci_dev, dev->state.pci_cfg); -#else pci_restore_state(pci_dev); -#endif #if 1 /* FIXME: re-initialize hardware */ diff --git a/linux/drivers/media/video/cx88/cx88-tvaudio.c b/linux/drivers/media/video/cx88/cx88-tvaudio.c index b4dab2647..5eb95dbbe 100644 --- a/linux/drivers/media/video/cx88/cx88-tvaudio.c +++ b/linux/drivers/media/video/cx88/cx88-tvaudio.c @@ -53,9 +53,7 @@ #include <linux/vmalloc.h> #include <linux/init.h> #include <linux/delay.h> -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) #include <linux/kthread.h> -#endif #include "cx88.h" diff --git a/linux/drivers/media/video/cx88/cx88-video.c b/linux/drivers/media/video/cx88/cx88-video.c index c9f7d0048..63521066d 100644 --- a/linux/drivers/media/video/cx88/cx88-video.c +++ b/linux/drivers/media/video/cx88/cx88-video.c @@ -35,9 +35,7 @@ #include <linux/dma-mapping.h> #include <linux/delay.h> #include "compat.h" -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) #include <linux/kthread.h> -#endif #include <asm/div64.h> #include "cx88.h" @@ -58,22 +56,9 @@ static unsigned int video_nr[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; static unsigned int vbi_nr[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; static unsigned int radio_nr[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -MODULE_PARM(video_nr,"1-" __stringify(CX88_MAXBOARDS) "i"); -MODULE_PARM(vbi_nr,"1-" __stringify(CX88_MAXBOARDS) "i"); -MODULE_PARM(radio_nr,"1-" __stringify(CX88_MAXBOARDS) "i"); -#else -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) -static unsigned int dummy; -module_param_array(video_nr, int, dummy, 0444); -module_param_array(vbi_nr, int, dummy, 0444); -module_param_array(radio_nr, int, dummy, 0444); -#else module_param_array(video_nr, int, NULL, 0444); module_param_array(vbi_nr, int, NULL, 0444); module_param_array(radio_nr, int, NULL, 0444); -#endif -#endif MODULE_PARM_DESC(video_nr,"video device numbers"); MODULE_PARM_DESC(vbi_nr,"vbi device numbers"); @@ -1963,9 +1948,7 @@ static const struct file_operations video_fops = .poll = video_poll, .mmap = video_mmap, .ioctl = video_ioctl2, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) .compat_ioctl = v4l_compat_ioctl32, -#endif .llseek = no_llseek, }; @@ -2018,9 +2001,7 @@ static const struct file_operations radio_fops = .open = video_open, .release = video_release, .ioctl = video_ioctl2, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) .compat_ioctl = v4l_compat_ioctl32, -#endif .llseek = no_llseek, }; @@ -2221,7 +2202,6 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, mutex_unlock(&core->lock); /* start tvaudio thread */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) if (core->board.tuner_type != TUNER_ABSENT) { core->kthread = kthread_run(cx88_audio_thread, core, "cx88 tvaudio"); if (IS_ERR(core->kthread)) { @@ -2230,13 +2210,6 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, core->name, err); } } -#else - /*FIXME: Not sure if this will work */ - if (core->board.tuner_type != TUNER_ABSENT) - kernel_thread (cx88_audio_thread, core, 0); - - core->kthread = NULL; -#endif return 0; fail_unreg: @@ -2306,11 +2279,7 @@ static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state) cx88_shutdown(core); #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) - pci_save_state(pci_dev, dev->state.pci_cfg); -#else pci_save_state(pci_dev); -#endif if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) { pci_disable_device(pci_dev); dev->state.disabled = 1; @@ -2342,11 +2311,7 @@ static int cx8800_resume(struct pci_dev *pci_dev) return err; } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) - pci_restore_state(pci_dev, dev->state.pci_cfg); -#else pci_restore_state(pci_dev); -#endif #if 1 /* FIXME: re-initialize hardware */ diff --git a/linux/drivers/media/video/cx88/cx88-vp3054-i2c.c b/linux/drivers/media/video/cx88/cx88-vp3054-i2c.c index 84bb59175..20800425c 100644 --- a/linux/drivers/media/video/cx88/cx88-vp3054-i2c.c +++ b/linux/drivers/media/video/cx88/cx88-vp3054-i2c.c @@ -30,10 +30,6 @@ #include "cx88.h" #include "cx88-vp3054-i2c.h" -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include "i2c-compat.h" -#endif - MODULE_DESCRIPTION("driver for cx2388x VP3054 design"); MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); MODULE_LICENSE("GPL"); @@ -124,18 +120,12 @@ int vp3054_i2c_probe(struct cx8802_dev *dev) memcpy(&vp3054_i2c->algo, &vp3054_i2c_algo_template, sizeof(vp3054_i2c->algo)); -#ifdef I2C_CLASS_TV_DIGITAL vp3054_i2c->adap.class |= I2C_CLASS_TV_DIGITAL; -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,66) vp3054_i2c->adap.dev.parent = &dev->pci->dev; -#endif strlcpy(vp3054_i2c->adap.name, core->name, sizeof(vp3054_i2c->adap.name)); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) vp3054_i2c->adap.owner = THIS_MODULE; -#endif vp3054_i2c->adap.id = I2C_HW_B_CX2388x; vp3054_i2c->algo.data = dev; i2c_set_adapdata(&vp3054_i2c->adap, dev); diff --git a/linux/drivers/media/video/cx88/cx88.h b/linux/drivers/media/video/cx88/cx88.h index 4222f919e..161b3cc13 100644 --- a/linux/drivers/media/video/cx88/cx88.h +++ b/linux/drivers/media/video/cx88/cx88.h @@ -386,9 +386,6 @@ struct cx8800_fh { }; struct cx8800_suspend_state { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) - u32 pci_cfg[64 / sizeof(u32)]; -#endif int disabled; }; @@ -445,9 +442,6 @@ struct cx8802_fh { }; struct cx8802_suspend_state { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) - u32 pci_cfg[64 / sizeof(u32)]; -#endif int disabled; }; diff --git a/linux/drivers/media/video/em28xx/em28xx-dvb.c b/linux/drivers/media/video/em28xx/em28xx-dvb.c index c04e62739..b8a5c61ce 100644 --- a/linux/drivers/media/video/em28xx/em28xx-dvb.c +++ b/linux/drivers/media/video/em28xx/em28xx-dvb.c @@ -63,11 +63,7 @@ struct em28xx_dvb { int nfeeds; /* general boilerplate stuff */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) struct dvb_adapter adapter; -#else - struct dvb_adapter *adapter; -#endif struct dvb_demux demux; struct dmxdev dmxdev; struct dmx_frontend fe_hw; @@ -303,17 +299,10 @@ int register_dvb(struct em28xx_dvb *dvb, /* Ensure all frontends negotiate bus access */ dvb->frontend->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) dvb->adapter.priv = dev; /* register frontend */ result = dvb_register_frontend(&dvb->adapter, dvb->frontend); -#else - dvb->adapter->priv = dev; - - /* register frontend */ - result = dvb_register_frontend(dvb->adapter, dvb->frontend); -#endif if (result < 0) { printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n", dev->name, result); @@ -340,11 +329,7 @@ int register_dvb(struct em28xx_dvb *dvb, dvb->dmxdev.filternum = 256; dvb->dmxdev.demux = &dvb->demux.dmx; dvb->dmxdev.capabilities = 0; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); -#else - result = dvb_dmxdev_init(&dvb->dmxdev, dvb->adapter); -#endif if (result < 0) { printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n", dev->name, result); @@ -375,11 +360,7 @@ int register_dvb(struct em28xx_dvb *dvb, } /* register network adapter */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); -#else - dvb_net_init(dvb->adapter, &dvb->net, &dvb->demux.dmx); -#endif return 0; fail_fe_conn: @@ -394,11 +375,7 @@ fail_dmx: dvb_unregister_frontend(dvb->frontend); fail_frontend: dvb_frontend_detach(dvb->frontend); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) dvb_unregister_adapter(&dvb->adapter); -#else - dvb_unregister_adapter(dvb->adapter); -#endif fail_adapter: return result; } @@ -412,11 +389,7 @@ static void unregister_dvb(struct em28xx_dvb *dvb) dvb_dmx_release(&dvb->demux); dvb_unregister_frontend(dvb->frontend); dvb_frontend_detach(dvb->frontend); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) dvb_unregister_adapter(&dvb->adapter); -#else - dvb_unregister_adapter(dvb->adapter); -#endif } diff --git a/linux/drivers/media/video/em28xx/em28xx-i2c.c b/linux/drivers/media/video/em28xx/em28xx-i2c.c index c22e73019..4d6f650da 100644 --- a/linux/drivers/media/video/em28xx/em28xx-i2c.c +++ b/linux/drivers/media/video/em28xx/em28xx-i2c.c @@ -432,18 +432,6 @@ static u32 functionality(struct i2c_adapter *adap) return I2C_FUNC_SMBUS_EMUL; } -#ifndef I2C_PEC -static void inc_use(struct i2c_adapter *adap) -{ - MOD_INC_USE_COUNT; -} - -static void dec_use(struct i2c_adapter *adap) -{ - MOD_DEC_USE_COUNT; -} -#endif - /* * attach_inform() * gets called when a device attaches to the i2c bus @@ -521,15 +509,8 @@ static struct i2c_algorithm em28xx_algo = { }; static struct i2c_adapter em28xx_adap_template = { -#ifdef I2C_PEC .owner = THIS_MODULE, -#else - .inc_use = inc_use, - .dec_use = dec_use, -#endif -#ifdef I2C_CLASS_TV_ANALOG .class = I2C_CLASS_TV_ANALOG, -#endif .name = "em28xx", .id = I2C_HW_B_EM28XX, .algo = &em28xx_algo, diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c index f4479aeca..5929d0860 100644 --- a/linux/drivers/media/video/em28xx/em28xx-video.c +++ b/linux/drivers/media/video/em28xx/em28xx-video.c @@ -42,9 +42,6 @@ #include <media/v4l2-common.h> #include <media/msp3400.h> #include <media/tuner.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -#include "i2c-compat.h" -#endif #define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \ "Markus Rechberger <mrechberger@gmail.com>, " \ @@ -83,25 +80,10 @@ static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; static unsigned int vbi_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; static unsigned int radio_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -MODULE_PARM(card, "1-" __stringify(EM28XX_MAXBOARDS) "i"); -MODULE_PARM(video_nr, "1-" __stringify(EM28XX_MAXBOARDS) "i"); -MODULE_PARM(vbi_nr, "1-" __stringify(EM28XX_MAXBOARDS) "i"); -MODULE_PARM(radio_nr, "1-" __stringify(EM28XX_MAXBOARDS) "i"); -#else -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10) -static int dummy; -module_param_array(card, int, dummy, 0444); -module_param_array(video_nr, int, dummy, 0444); -module_param_array(vbi_nr, int, dummy, 0444); -module_param_array(radio_nr, int, dummy, 0444); -#else module_param_array(card, int, NULL, 0444); module_param_array(video_nr, int, NULL, 0444); module_param_array(vbi_nr, int, NULL, 0444); module_param_array(radio_nr, int, NULL, 0444); -#endif -#endif MODULE_PARM_DESC(card, "card type"); MODULE_PARM_DESC(video_nr, "video device numbers"); MODULE_PARM_DESC(vbi_nr, "vbi device numbers"); @@ -1837,9 +1819,7 @@ static const struct file_operations em28xx_v4l_fops = { .mmap = em28xx_v4l2_mmap, .ioctl = video_ioctl2, .llseek = no_llseek, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) .compat_ioctl = v4l_compat_ioctl32, -#endif }; static const struct file_operations radio_fops = { @@ -1847,9 +1827,7 @@ static const struct file_operations radio_fops = { .open = em28xx_v4l2_open, .release = em28xx_v4l2_close, .ioctl = video_ioctl2, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) .compat_ioctl = v4l_compat_ioctl32, -#endif .llseek = no_llseek, }; @@ -1978,10 +1956,8 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev, return NULL; *vfd = *template; vfd->minor = -1; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0) vfd->dev = &dev->udev->dev; vfd->release = video_device_release; -#endif vfd->type = type; vfd->debug = video_debug; @@ -2167,9 +2143,6 @@ static void request_module_async(struct work_struct *work) request_module("em28xx-dvb"); } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -#define request_modules(dev) -#else static void request_modules(struct em28xx *dev) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) @@ -2180,7 +2153,6 @@ static void request_modules(struct em28xx *dev) #endif schedule_work(&dev->request_module_wk); } -#endif #else #define request_modules(dev) #endif /* CONFIG_MODULES */ diff --git a/linux/drivers/media/video/ir-kbd-i2c.c b/linux/drivers/media/video/ir-kbd-i2c.c index 9a8795523..85806fe10 100644 --- a/linux/drivers/media/video/ir-kbd-i2c.c +++ b/linux/drivers/media/video/ir-kbd-i2c.c @@ -328,10 +328,8 @@ static int ir_detach(struct i2c_client *client); static int ir_probe(struct i2c_adapter *adap); static struct i2c_driver driver = { -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))&&(LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)) +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) .owner = THIS_MODULE, -#endif -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) .name = "ir-kbd-i2c", .flags = I2C_DF_NOTIFY, #else diff --git a/linux/drivers/media/video/ivtv/ivtv-i2c.c b/linux/drivers/media/video/ivtv/ivtv-i2c.c index b9e38c849..3446ab458 100644 --- a/linux/drivers/media/video/ivtv/ivtv-i2c.c +++ b/linux/drivers/media/video/ivtv/ivtv-i2c.c @@ -75,10 +75,6 @@ #define IVTV_REG_I2C_GETSCL_OFFSET 0x7008 #define IVTV_REG_I2C_GETSDA_OFFSET 0x700c -#ifndef I2C_ADAP_CLASS_TV_ANALOG -#define I2C_ADAP_CLASS_TV_ANALOG I2C_CLASS_TV_ANALOG -#endif /* I2C_ADAP_CLASS_TV_ANALOG */ - #define IVTV_CS53L32A_I2C_ADDR 0x11 #define IVTV_M52790_I2C_ADDR 0x48 #define IVTV_CX25840_I2C_ADDR 0x44 @@ -564,9 +560,7 @@ static struct i2c_adapter ivtv_i2c_adap_hw_template = { .client_unregister = detach_inform, .owner = THIS_MODULE, #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) -#ifdef I2C_ADAP_CLASS_TV_ANALOG - .class = I2C_ADAP_CLASS_TV_ANALOG, -#endif + .class = I2C_CLASS_TV_ANALOG, #endif }; @@ -622,9 +616,7 @@ static struct i2c_adapter ivtv_i2c_adap_template = { .client_unregister = detach_inform, .owner = THIS_MODULE, #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) -#ifdef I2C_ADAP_CLASS_TV_ANALOG - .class = I2C_ADAP_CLASS_TV_ANALOG, -#endif + .class = I2C_CLASS_TV_ANALOG, #endif }; diff --git a/linux/drivers/media/video/ivtv/ivtv-streams.c b/linux/drivers/media/video/ivtv/ivtv-streams.c index d2dd89519..f8883b487 100644 --- a/linux/drivers/media/video/ivtv/ivtv-streams.c +++ b/linux/drivers/media/video/ivtv/ivtv-streams.c @@ -49,9 +49,7 @@ static const struct file_operations ivtv_v4l2_enc_fops = { .write = ivtv_v4l2_write, .open = ivtv_v4l2_open, .ioctl = ivtv_v4l2_ioctl, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) .compat_ioctl = v4l_compat_ioctl32, -#endif .release = ivtv_v4l2_close, .poll = ivtv_v4l2_enc_poll, }; @@ -62,9 +60,7 @@ static const struct file_operations ivtv_v4l2_dec_fops = { .write = ivtv_v4l2_write, .open = ivtv_v4l2_open, .ioctl = ivtv_v4l2_ioctl, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) .compat_ioctl = v4l_compat_ioctl32, -#endif .release = ivtv_v4l2_close, .poll = ivtv_v4l2_dec_poll, }; diff --git a/linux/drivers/media/video/m52790.c b/linux/drivers/media/video/m52790.c index 77536ccfc..87e948caf 100644 --- a/linux/drivers/media/video/m52790.c +++ b/linux/drivers/media/video/m52790.c @@ -31,10 +31,6 @@ #include <media/v4l2-common.h> #include <media/v4l2-chip-ident.h> #include <media/v4l2-i2c-drv.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -#include "i2c-compat.h" -#include <linux/slab.h> -#endif #include "compat.h" MODULE_DESCRIPTION("i2c device driver for m52790 A/V switch"); @@ -44,10 +40,6 @@ MODULE_LICENSE("GPL"); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) static unsigned short normal_i2c[] = { 0x90 >> 1, I2C_CLIENT_END }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif - I2C_CLIENT_INSMOD; #endif @@ -193,7 +185,3 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .id_table = m52790_id, #endif }; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -EXPORT_NO_SYMBOLS; -#endif diff --git a/linux/drivers/media/video/msp3400-driver.c b/linux/drivers/media/video/msp3400-driver.c index 5ea4fd801..cd92f1f68 100644 --- a/linux/drivers/media/video/msp3400-driver.c +++ b/linux/drivers/media/video/msp3400-driver.c @@ -57,17 +57,12 @@ #include <media/v4l2-i2c-drv-legacy.h> #include <media/tvaudio.h> #include <media/msp3400.h> -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0) #include <linux/kthread.h> #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) #include <linux/suspend.h> #else #include <linux/freezer.h> #endif -#endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -#include "i2c-compat.h" -#endif #include "compat.h" #include "msp3400-driver.h" @@ -90,7 +85,6 @@ int msp_dolby; int msp_stereo_thresh = 0x190; /* a2 threshold for stereo/bilingual (msp34xxg only) 0x00a0-0x03c0 */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) /* read-only */ module_param(opmode, int, 0444); @@ -101,15 +95,6 @@ module_param_named(stereo_threshold, msp_stereo_thresh, int, 0644); module_param_named(standard, msp_standard, int, 0644); module_param_named(amsound, msp_amsound, bool, 0644); module_param_named(dolby, msp_dolby, bool, 0644); -#else -MODULE_PARM(opmode, "i"); -MODULE_PARM(msp_once, "i"); -MODULE_PARM(msp_debug, "i"); -MODULE_PARM(msp_stereo_thresh, "i"); -MODULE_PARM(msp_standard, "i"); -MODULE_PARM(msp_amsound, "i"); -MODULE_PARM(msp_dolby, "i"); -#endif MODULE_PARM_DESC(opmode, "Forces a MSP3400 opmode. 0=Manual, 1=Autodetect, 2=Autodetect and autoselect"); MODULE_PARM_DESC(once, "No continuous stereo monitoring"); @@ -130,9 +115,7 @@ MODULE_PARM_DESC(dolby, "Activates Dolby processsing"); /* Addresses to scan */ static unsigned short normal_i2c[] = { 0x80 >> 1, 0x88 >> 1, I2C_CLIENT_END }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif + I2C_CLIENT_INSMOD; /* ----------------------------------------------------------------------- */ @@ -356,24 +339,6 @@ void msp_set_audio(struct i2c_client *client) /* ------------------------------------------------------------------------ */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -static void msp_setup_thread(struct msp_state *state) -{ - daemonize(); - exit_files(current); - reparent_to_init(); - - spin_lock_irq(SIGMASK_LOCK(current)); - sigfillset(¤t->blocked); - spin_unlock_irq(SIGMASK_LOCK(current)); - strcpy(current->comm, "msp3400"); - - state->kthread = current; - if (state->notify != NULL) - up(state->notify); -} -#endif - static void msp_wake_thread(struct i2c_client *client) { struct msp_state *state = i2c_get_clientdata(client); @@ -390,11 +355,7 @@ int msp_sleep(struct msp_state *state, int timeout) DECLARE_WAITQUEUE(wait, current); add_wait_queue(&state->wq, &wait); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) - if (!(state->rmmod || signal_pending(current))) { -#else if (!kthread_should_stop()) { -#endif if (timeout < 0) { set_current_state(TASK_INTERRUPTIBLE); schedule(); @@ -1018,20 +979,10 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id) /* startup control thread if needed */ if (thread_func) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0) state->kthread = kthread_run(thread_func, client, "msp34xx"); if (IS_ERR(state->kthread)) v4l_warn(client, "kernel_thread() failed\n"); -#else - DECLARE_MUTEX_LOCKED(sem); - - state->kthread = NULL; - state->notify = &sem; - kernel_thread(thread_func, client, 0); - down(&sem); - state->notify = NULL; -#endif msp_wake_thread(client); } return 0; @@ -1043,20 +994,8 @@ static int msp_remove(struct i2c_client *client) /* shutdown control thread */ if (state->kthread) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) - DECLARE_MUTEX_LOCKED(sem); -#endif state->restart = 1; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) - /* shutdown control thread */ - state->notify = &sem; - state->rmmod = 1; - wake_up_interruptible(&state->wq); - down(&sem); - state->notify = NULL; -#else kthread_stop(state->kthread); -#endif } msp_reset(client); @@ -1087,10 +1026,6 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { #endif }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -EXPORT_NO_SYMBOLS; -#endif - /* * Overrides for Emacs so that we follow Linus's tabbing style. * --------------------------------------------------------------------------- diff --git a/linux/drivers/media/video/msp3400-driver.h b/linux/drivers/media/video/msp3400-driver.h index 20337567b..ab69a290e 100644 --- a/linux/drivers/media/video/msp3400-driver.h +++ b/linux/drivers/media/video/msp3400-driver.h @@ -92,10 +92,6 @@ struct msp_state { /* thread */ struct task_struct *kthread; wait_queue_head_t wq; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) - struct semaphore *notify; - int rmmod:1; -#endif unsigned int restart:1; unsigned int watch_stereo:1; }; diff --git a/linux/drivers/media/video/msp3400-kthreads.c b/linux/drivers/media/video/msp3400-kthreads.c index 0280feaac..ba19edac0 100644 --- a/linux/drivers/media/video/msp3400-kthreads.c +++ b/linux/drivers/media/video/msp3400-kthreads.c @@ -31,13 +31,8 @@ #include <linux/videodev2.h> #include <media/v4l2-common.h> #include <media/msp3400.h> -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0) #include <linux/kthread.h> #include <linux/suspend.h> -#endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -#include "i2c-compat.h" -#endif #include "compat.h" #include "msp3400-driver.h" @@ -488,10 +483,6 @@ int msp3400c_thread(void *data) struct msp3400c_carrier_detect *cd; int count, max1, max2, val1, val2, val, i; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) - msp_setup_thread(state); -#endif - v4l_dbg(1, msp_debug, client, "msp3400 daemon started\n"); set_freezable(); for (;;) { @@ -502,11 +493,7 @@ int msp3400c_thread(void *data) restart: v4l_dbg(2, msp_debug, client, "thread: restart scan\n"); state->restart = 0; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) - if (state->rmmod || signal_pending(current)) -#else if (kthread_should_stop()) -#endif break; if (state->radio || MSP_MODE_EXTERN == state->mode) { @@ -669,12 +656,6 @@ no_second: } } v4l_dbg(1, msp_debug, client, "thread: exit\n"); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) - state->kthread = NULL; - - if (state->notify != NULL) - up(state->notify); -#endif return 0; } @@ -685,9 +666,6 @@ int msp3410d_thread(void *data) struct msp_state *state = i2c_get_clientdata(client); int val, i, std, count; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) - msp_setup_thread(state); -#endif v4l_dbg(1, msp_debug, client, "msp3410 daemon started\n"); set_freezable(); for (;;) { @@ -698,11 +676,7 @@ int msp3410d_thread(void *data) restart: v4l_dbg(2, msp_debug, client, "thread: restart scan\n"); state->restart = 0; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) - if (state->rmmod || signal_pending(current)) -#else if (kthread_should_stop()) -#endif break; if (state->mode == MSP_MODE_EXTERN) { @@ -842,12 +816,6 @@ restart: } } v4l_dbg(1, msp_debug, client, "thread: exit\n"); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) - state->kthread = NULL; - - if (state->notify != NULL) - up(state->notify); -#endif return 0; } @@ -993,9 +961,6 @@ int msp34xxg_thread(void *data) struct msp_state *state = i2c_get_clientdata(client); int val, i; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) - msp_setup_thread(state); -#endif v4l_dbg(1, msp_debug, client, "msp34xxg daemon started\n"); set_freezable(); for (;;) { @@ -1006,11 +971,7 @@ int msp34xxg_thread(void *data) restart: v4l_dbg(1, msp_debug, client, "thread: restart scan\n"); state->restart = 0; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) - if (state->rmmod || signal_pending(current)) -#else if (kthread_should_stop()) -#endif break; if (state->mode == MSP_MODE_EXTERN) { @@ -1087,12 +1048,6 @@ unmute: } } v4l_dbg(1, msp_debug, client, "thread: exit\n"); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) - state->kthread = NULL; - - if (state->notify != NULL) - up(state->notify); -#endif return 0; } diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c index cf56b10d9..cbf848e82 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -3120,9 +3120,6 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw, write_len, pvr2_ctl_write_complete, hdw); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) - hdw->ctl_write_urb->transfer_flags |= URB_ASYNC_UNLINK; -#endif hdw->ctl_write_urb->actual_length = 0; hdw->ctl_write_pend_flag = !0; status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL); @@ -3147,9 +3144,6 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw, read_len, pvr2_ctl_read_complete, hdw); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) - hdw->ctl_read_urb->transfer_flags |= URB_ASYNC_UNLINK; -#endif hdw->ctl_read_urb->actual_length = 0; hdw->ctl_read_pend_flag = !0; status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL); diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c index 362ec49f5..797017066 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c @@ -1017,9 +1017,6 @@ static int pvr2_i2c_detach_inform(struct i2c_client *client) } static struct i2c_algorithm pvr2_i2c_algo_template = { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) - .id = I2C_HW_B_BT848, -#endif .master_xfer = pvr2_i2c_xfer, .functionality = pvr2_i2c_functionality, }; @@ -1081,9 +1078,6 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw) memcpy(&hdw->i2c_algo,&pvr2_i2c_algo_template,sizeof(hdw->i2c_algo)); strlcpy(hdw->i2c_adap.name,hdw->name,sizeof(hdw->i2c_adap.name)); hdw->i2c_adap.dev.parent = &hdw->usb_dev->dev; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) - strlcpy(hdw->i2c_algo.name,hdw->name,sizeof(hdw->i2c_algo.name)); -#endif hdw->i2c_adap.algo = &hdw->i2c_algo; hdw->i2c_adap.algo_data = hdw; hdw->i2c_pend_mask = 0; diff --git a/linux/drivers/media/video/pwc/pwc-ctrl.c b/linux/drivers/media/video/pwc/pwc-ctrl.c index 04fbd2749..1cccd5c77 100644 --- a/linux/drivers/media/video/pwc/pwc-ctrl.c +++ b/linux/drivers/media/video/pwc/pwc-ctrl.c @@ -1255,8 +1255,6 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor) exactly the same otherwise. */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) - /* define local variable for arg */ #define ARG_DEF(ARG_type, ARG_name)\ ARG_type *ARG_name = arg; @@ -1269,25 +1267,6 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor) /* copy local variable to arg */ #define ARG_OUT(ARG_name) /* nothing */ -#else - -#define ARG_DEF(ARG_type, ARG_name)\ - ARG_type ARG_name; -#define ARG_IN(ARG_name)\ - if (copy_from_user(&ARG_name, arg, sizeof(ARG_name))) {\ - ret = -EFAULT;\ - break;\ - } -#define ARGR(ARG_name) ARG_name -#define ARGA(ARG_name) &ARG_name -#define ARG_OUT(ARG_name)\ - if (copy_to_user(arg, &ARG_name, sizeof(ARG_name))) {\ - ret = -EFAULT;\ - break;\ - } - -#endif - int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) { int ret = 0; diff --git a/linux/drivers/media/video/pwc/pwc-if.c b/linux/drivers/media/video/pwc/pwc-if.c index 8236b2b2d..c28490ae5 100644 --- a/linux/drivers/media/video/pwc/pwc-if.c +++ b/linux/drivers/media/video/pwc/pwc-if.c @@ -830,13 +830,9 @@ int pwc_isoc_init(struct pwc_device *pdev) /* Get the current alternate interface, adjust packet size */ if (!udev->actconfig) return -EFAULT; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) - idesc = &udev->actconfig->interface[0]->altsetting[pdev->valternate]; -#else intf = usb_ifnum_to_if(udev, 0); if (intf) idesc = usb_altnum_to_altsetting(intf, pdev->valternate); -#endif if (!idesc) return -EFAULT; @@ -845,11 +841,7 @@ int pwc_isoc_init(struct pwc_device *pdev) pdev->vmax_packet_size = -1; for (i = 0; i < idesc->desc.bNumEndpoints; i++) { if ((idesc->endpoint[i].desc.bEndpointAddress & 0xF) == pdev->vendpoint) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) - pdev->vmax_packet_size = idesc->endpoint[i].desc.wMaxPacketSize; -#else pdev->vmax_packet_size = le16_to_cpu(idesc->endpoint[i].desc.wMaxPacketSize); -#endif break; } } @@ -1472,15 +1464,9 @@ static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) pos += (unsigned long)pdev->image_data; while (size > 0) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) - page = kvirt_to_pa(pos); - if (remap_page_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) - return -EAGAIN; -#else page = vmalloc_to_pfn((void *)pos); if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) return -EAGAIN; -#endif start += PAGE_SIZE; pos += PAGE_SIZE; if (size > PAGE_SIZE) @@ -1508,13 +1494,8 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id int video_nr = -1; /* default: use next available device */ char serial_number[30], *name; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) - vendor_id = udev->descriptor.idVendor; - product_id = udev->descriptor.idProduct; -#else vendor_id = le16_to_cpu(udev->descriptor.idVendor); product_id = le16_to_cpu(udev->descriptor.idProduct); -#endif /* Check if we can handle this device */ PWC_DEBUG_PROBE("probe() called [%04X %04X], if %d\n", @@ -1795,11 +1776,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id pdev->vdev->owner = THIS_MODULE; video_set_drvdata(pdev->vdev, pdev); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) - pdev->release = udev->descriptor.bcdDevice; -#else pdev->release = le16_to_cpu(udev->descriptor.bcdDevice); -#endif PWC_DEBUG_PROBE("Release: %04x\n", pdev->release); /* Now search device_hint[] table for a match, so we can hint a node number. */ @@ -1943,13 +1920,8 @@ module_param_named(trace, pwc_trace, int, 0644); #endif module_param(power_save, int, 0444); module_param(compression, int, 0444); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) -module_param_array(leds, int, leds_nargs, 0444); -module_param_array(dev_hint, charp, dev_hint_nargs, 0444); -#else module_param_array(leds, int, &leds_nargs, 0444); module_param_array(dev_hint, charp, &dev_hint_nargs, 0444); -#endif MODULE_PARM_DESC(size, "Initial image size. One of sqcif, qsif, qcif, sif, cif, vga"); MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30"); diff --git a/linux/drivers/media/video/pwc/pwc-ioctl.h b/linux/drivers/media/video/pwc/pwc-ioctl.h index 58904acda..8c0cae7b3 100644 --- a/linux/drivers/media/video/pwc/pwc-ioctl.h +++ b/linux/drivers/media/video/pwc/pwc-ioctl.h @@ -54,11 +54,6 @@ #include <linux/types.h> #include <linux/version.h> -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 10) -/* Compatibility for older kernel */ -typedef __u16 __le16; -#endif - /* Enumeration of image sizes */ #define PSZ_SQCIF 0x00 #define PSZ_QSIF 0x01 diff --git a/linux/drivers/media/video/saa5246a.c b/linux/drivers/media/video/saa5246a.c index 900185cf2..2ea5d70a9 100644 --- a/linux/drivers/media/video/saa5246a.c +++ b/linux/drivers/media/video/saa5246a.c @@ -73,9 +73,7 @@ static struct video_device saa_template; /* Declared near bottom */ /* Addresses to scan */ static unsigned short normal_i2c[] = { I2C_ADDRESS, I2C_CLIENT_END }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif + I2C_CLIENT_INSMOD; static struct i2c_client client_template; diff --git a/linux/drivers/media/video/saa5249.c b/linux/drivers/media/video/saa5249.c index be71833d0..4443a023c 100644 --- a/linux/drivers/media/video/saa5249.c +++ b/linux/drivers/media/video/saa5249.c @@ -137,9 +137,7 @@ static struct video_device saa_template; /* Declared near bottom */ /* Addresses to scan */ static unsigned short normal_i2c[] = {34>>1,I2C_CLIENT_END}; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif + I2C_CLIENT_INSMOD; static struct i2c_client client_template; diff --git a/linux/drivers/media/video/saa6588.c b/linux/drivers/media/video/saa6588.c index 0774c351a..5efa5ab66 100644 --- a/linux/drivers/media/video/saa6588.c +++ b/linux/drivers/media/video/saa6588.c @@ -31,10 +31,6 @@ #include <linux/wait.h> #include <asm/uaccess.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include "i2c-compat.h" -#endif - #include <media/rds.h> #include "compat.h" @@ -45,9 +41,6 @@ static unsigned short normal_i2c[] = { I2C_CLIENT_END, }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif I2C_CLIENT_INSMOD; /* insmod options */ @@ -404,11 +397,7 @@ static int saa6588_configure(struct saa6588 *s) /* ---------------------------------------------------------------------- */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) static int saa6588_attach(struct i2c_adapter *adap, int addr, int kind) -#else -static int saa6588_attach(struct i2c_adapter *adap, int addr, unsigned short flags, int kind) -#endif { struct saa6588 *s; client_template.adapter = adap; @@ -448,28 +437,13 @@ static int saa6588_attach(struct i2c_adapter *adap, int addr, unsigned short fla s->timer.function = saa6588_timer; s->timer.data = (unsigned long)s; schedule_work(&s->work); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - MOD_INC_USE_COUNT; -#endif return 0; } static int saa6588_probe(struct i2c_adapter *adap) { -#ifdef I2C_CLASS_TV_ANALOG if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, saa6588_attach); -#else - switch (adap->id) { - case I2C_HW_B_BT848: - case I2C_HW_B_RIVA: -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - case I2C_HW_SAA7134: -#endif - return i2c_probe(adap, &addr_data, saa6588_attach); - break; - } -#endif return 0; } @@ -526,10 +500,8 @@ static int saa6588_command(struct i2c_client *client, unsigned int cmd, /* ----------------------------------------------------------------------- */ static struct i2c_driver driver = { -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)) && ( LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)) +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) .owner = THIS_MODULE, -#endif -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) .name = "saa6588", .flags = I2C_DF_NOTIFY, #else diff --git a/linux/drivers/media/video/saa7115.c b/linux/drivers/media/video/saa7115.c index fc4c17bbd..5d99f8455 100644 --- a/linux/drivers/media/video/saa7115.c +++ b/linux/drivers/media/video/saa7115.c @@ -48,9 +48,6 @@ #include <media/v4l2-chip-ident.h> #include <media/v4l2-i2c-drv-legacy.h> #include <media/saa7115.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include "i2c-compat.h" -#endif #include <asm/div64.h> #include "compat.h" @@ -62,11 +59,7 @@ MODULE_AUTHOR( "Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, " MODULE_LICENSE("GPL"); static int debug; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) module_param(debug, bool, 0644); -#else -MODULE_PARM(debug, "i"); -#endif MODULE_PARM_DESC(debug, "Debug level (0-1)"); @@ -75,10 +68,6 @@ static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */ I2C_CLIENT_END }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif - I2C_CLIENT_INSMOD; struct saa711x_state { @@ -1595,14 +1584,8 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .command = saa7115_command, .probe = saa7115_probe, .remove = saa7115_remove, -#ifdef I2C_CLASS_TV_ANALOG .legacy_class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL, -#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) .id_table = saa7115_id, #endif }; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -EXPORT_NO_SYMBOLS; -#endif diff --git a/linux/drivers/media/video/saa7127.c b/linux/drivers/media/video/saa7127.c index a73ae00af..28905adfb 100644 --- a/linux/drivers/media/video/saa7127.c +++ b/linux/drivers/media/video/saa7127.c @@ -57,9 +57,6 @@ #include <media/v4l2-chip-ident.h> #include <media/v4l2-i2c-drv.h> #include <media/saa7127.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -#include "i2c-compat.h" -#endif #include "compat.h" static int debug; @@ -68,23 +65,14 @@ static int test_image; MODULE_DESCRIPTION("Philips SAA7127/9 video encoder driver"); MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil"); MODULE_LICENSE("GPL"); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) module_param(debug, int, 0644); module_param(test_image, int, 0644); -#else -MODULE_PARM(debug, "i"); -MODULE_PARM(test_image, "i"); -#endif MODULE_PARM_DESC(debug, "debug level (0-2)"); MODULE_PARM_DESC(test_image, "test_image (0-1)"); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif - I2C_CLIENT_INSMOD; #endif @@ -779,7 +767,3 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .id_table = saa7127_id, #endif }; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -EXPORT_NO_SYMBOLS; -#endif diff --git a/linux/drivers/media/video/saa7134/saa6752hs.c b/linux/drivers/media/video/saa7134/saa6752hs.c index c2b1be5d2..0143c8b28 100644 --- a/linux/drivers/media/video/saa7134/saa6752hs.c +++ b/linux/drivers/media/video/saa7134/saa6752hs.c @@ -14,10 +14,6 @@ #include <linux/init.h> #include <linux/crc32.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include "i2c-compat.h" -#endif - #define MPEG_VIDEO_TARGET_BITRATE_MAX 27000 #define MPEG_VIDEO_MAX_BITRATE_MAX 27000 #define MPEG_TOTAL_TARGET_BITRATE_MAX 27000 @@ -25,9 +21,7 @@ /* Addresses to scan */ static unsigned short normal_i2c[] = {0x20, I2C_CLIENT_END}; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif + I2C_CLIENT_INSMOD; MODULE_DESCRIPTION("device driver for saa6752hs MPEG2 encoder"); @@ -695,11 +689,7 @@ static int saa6752hs_init(struct i2c_client* client) return 0; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind) -#else -static int saa6752hs_attach(struct i2c_adapter *adap, int addr, unsigned short flags, int kind) -#endif { struct saa6752hs_state *h; @@ -718,21 +708,13 @@ static int saa6752hs_attach(struct i2c_adapter *adap, int addr, unsigned short f i2c_attach_client(&h->client); v4l_info(&h->client,"saa6752hs: chip found @ 0x%x\n", addr<<1); - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - MOD_INC_USE_COUNT; -#endif return 0; } static int saa6752hs_probe(struct i2c_adapter *adap) { -#if I2C_CLASS_TV_ANALOG if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, saa6752hs_attach); -#else - return i2c_probe(adap, &addr_data, saa6752hs_attach); -#endif return 0; } @@ -815,10 +797,8 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) /* ----------------------------------------------------------------------- */ static struct i2c_driver driver = { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))&&(LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)) +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) .owner = THIS_MODULE, -#endif -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) .name = "saa6752hs", .flags = I2C_DF_NOTIFY, #else diff --git a/linux/drivers/media/video/saa7134/saa7134-alsa.c b/linux/drivers/media/video/saa7134/saa7134-alsa.c index 900be78e3..6293eba34 100644 --- a/linux/drivers/media/video/saa7134/saa7134-alsa.c +++ b/linux/drivers/media/video/saa7134/saa7134-alsa.c @@ -16,7 +16,6 @@ * */ -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) #include <linux/init.h> #include <linux/slab.h> #include <linux/time.h> @@ -52,14 +51,8 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1}; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) -static int dummy; -module_param_array(index, int, dummy, 0444); -module_param_array(enable, int, dummy, 0444); -#else module_param_array(index, int, NULL, 0444); module_param_array(enable, int, NULL, 0444); -#endif MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s)."); MODULE_PARM_DESC(enable, "Enable (or not) the SAA7134 capture interface(s)."); @@ -88,10 +81,6 @@ typedef struct snd_card_saa7134 { } snd_card_saa7134_t; -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,8) -#define chip_t snd_card_saa7134_t -#endif - /* * PCM structure */ @@ -1136,7 +1125,3 @@ late_initcall(saa7134_alsa_init); module_exit(saa7134_alsa_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Ricardo Cerqueira"); - - -#endif /* LINUX_VERSION_CODE */ - diff --git a/linux/drivers/media/video/saa7134/saa7134-core.c b/linux/drivers/media/video/saa7134/saa7134-core.c index 9ed2997f7..511941bca 100644 --- a/linux/drivers/media/video/saa7134/saa7134-core.c +++ b/linux/drivers/media/video/saa7134/saa7134-core.c @@ -80,28 +80,11 @@ static unsigned int tuner[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; static unsigned int card[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -MODULE_PARM(video_nr,"1-" __stringify(SAA7134_MAXBOARDS) "i"); -MODULE_PARM(vbi_nr,"1-" __stringify(SAA7134_MAXBOARDS) "i"); -MODULE_PARM(radio_nr,"1-" __stringify(SAA7134_MAXBOARDS) "i"); -MODULE_PARM(tuner_nr,"1-" __stringify(SAA7134_MAXBOARDS) "i"); -MODULE_PARM(card,"1-" __stringify(SAA7134_MAXBOARDS) "i"); -#else -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) -static int dummy; -module_param_array(video_nr, int, dummy, 0444); -module_param_array(vbi_nr, int, dummy, 0444); -module_param_array(radio_nr, int, dummy, 0444); -module_param_array(tuner, int, dummy, 0444); -module_param_array(card, int, dummy, 0444); -#else module_param_array(video_nr, int, NULL, 0444); module_param_array(vbi_nr, int, NULL, 0444); module_param_array(radio_nr, int, NULL, 0444); module_param_array(tuner, int, NULL, 0444); module_param_array(card, int, NULL, 0444); -#endif -#endif MODULE_PARM_DESC(video_nr, "video device number"); MODULE_PARM_DESC(vbi_nr, "vbi device number"); @@ -209,20 +192,6 @@ static void dump_statusregs(struct saa7134_dev *dev) #if defined(CONFIG_MODULES) && defined(MODULE) -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - -static void request_submodules(struct saa7134_dev *dev){ - if (card_is_empress(dev)) - request_module("saa7134-empress"); - if (card_is_dvb(dev)) - request_module("saa7134-dvb"); - if (alsa) - request_module("saa7134-alsa"); - if (oss) - request_module("saa7134-oss"); -} -#else - #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) static void request_module_async(void *ptr){ struct saa7134_dev* dev=(struct saa7134_dev*)ptr; @@ -249,7 +218,6 @@ static void request_submodules(struct saa7134_dev *dev) #endif schedule_work(&dev->request_module_wk); } -#endif #else #define request_submodules(dev) @@ -893,10 +861,8 @@ static struct video_device *vdev_init(struct saa7134_dev *dev, return NULL; *vfd = *template; vfd->minor = -1; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) vfd->dev = &dev->pci->dev; vfd->release = video_device_release; -#endif vfd->debug = video_debug; snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type, saa7134_boards[dev->board].name); diff --git a/linux/drivers/media/video/saa7134/saa7134-empress.c b/linux/drivers/media/video/saa7134/saa7134-empress.c index 837470f4d..d4afbce9d 100644 --- a/linux/drivers/media/video/saa7134/saa7134-empress.c +++ b/linux/drivers/media/video/saa7134/saa7134-empress.c @@ -37,16 +37,7 @@ MODULE_LICENSE("GPL"); static unsigned int empress_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -MODULE_PARM(empress_nr,"1-" __stringify(SAA7134_MAXBOARDS) "i"); -#else -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) -static int dummy; -module_param_array(empress_nr, int, dummy, 0444); -#else module_param_array(empress_nr, int, NULL, 0444); -#endif -#endif MODULE_PARM_DESC(empress_nr,"ts device number"); static unsigned int debug; @@ -482,10 +473,8 @@ static int empress_init(struct saa7134_dev *dev) if (NULL == dev->empress_dev) return -ENOMEM; *(dev->empress_dev) = saa7134_empress_template; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) dev->empress_dev->dev = &dev->pci->dev; dev->empress_dev->release = video_device_release; -#endif snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name), "%s empress (%s)", dev->name, saa7134_boards[dev->board].name); diff --git a/linux/drivers/media/video/saa7134/saa7134-i2c.c b/linux/drivers/media/video/saa7134/saa7134-i2c.c index 64858dfe8..610e506b5 100644 --- a/linux/drivers/media/video/saa7134/saa7134-i2c.c +++ b/linux/drivers/media/video/saa7134/saa7134-i2c.c @@ -368,12 +368,8 @@ static struct i2c_algorithm saa7134_algo = { }; static struct i2c_adapter saa7134_adap_template = { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) .owner = THIS_MODULE, -#endif -#ifdef I2C_CLASS_TV_ANALOG .class = I2C_CLASS_TV_ANALOG, -#endif .name = "saa7134", .id = I2C_HW_SAA7134, .algo = &saa7134_algo, @@ -447,9 +443,7 @@ void saa7134_i2c_call_clients(struct saa7134_dev *dev, int saa7134_i2c_register(struct saa7134_dev *dev) { dev->i2c_adap = saa7134_adap_template; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,66) dev->i2c_adap.dev.parent = &dev->pci->dev; -#endif strcpy(dev->i2c_adap.name,dev->name); dev->i2c_adap.algo_data = dev; i2c_add_adapter(&dev->i2c_adap); diff --git a/linux/drivers/media/video/saa7134/saa7134-input.c b/linux/drivers/media/video/saa7134/saa7134-input.c index aecaa7cd0..c12184a38 100644 --- a/linux/drivers/media/video/saa7134/saa7134-input.c +++ b/linux/drivers/media/video/saa7134/saa7134-input.c @@ -463,7 +463,6 @@ int saa7134_input_init1(struct saa7134_dev *dev) ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); input_dev->name = ir->name; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) input_dev->phys = ir->phys; input_dev->id.bustype = BUS_PCI; input_dev->id.version = 1; @@ -483,7 +482,6 @@ int saa7134_input_init1(struct saa7134_dev *dev) input_dev->dev = &dev->pci->dev; #endif #endif -#endif dev->remote = ir; saa7134_ir_start(dev, ir); diff --git a/linux/drivers/media/video/saa7134/saa7134-tvaudio.c b/linux/drivers/media/video/saa7134/saa7134-tvaudio.c index a4fe3c41b..f7a3f1d0a 100644 --- a/linux/drivers/media/video/saa7134/saa7134-tvaudio.c +++ b/linux/drivers/media/video/saa7134/saa7134-tvaudio.c @@ -496,14 +496,6 @@ static int tvaudio_thread(void *data) unsigned int i, audio, nscan; int max1,max2,carrier,rx,mode,lastmode,default_carrier; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,61) - lock_kernel(); - daemonize(); - sigfillset(¤t->blocked); - sprintf(current->comm, "%s", dev->name); - unlock_kernel(); -#endif - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) set_freezable(); #endif @@ -821,14 +813,6 @@ static int tvaudio_thread_ddep(void *data) struct saa7134_dev *dev = data; u32 value, norms; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,61) - lock_kernel(); - daemonize(); - sigfillset(¤t->blocked); - sprintf(current->comm, "%s", dev->name); - unlock_kernel(); -#endif - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) set_freezable(); #endif diff --git a/linux/drivers/media/video/saa7134/saa7134-video.c b/linux/drivers/media/video/saa7134/saa7134-video.c index 33ad87e6b..e02bd2659 100644 --- a/linux/drivers/media/video/saa7134/saa7134-video.c +++ b/linux/drivers/media/video/saa7134/saa7134-video.c @@ -2356,9 +2356,7 @@ static const struct file_operations video_fops = .poll = video_poll, .mmap = video_mmap, .ioctl = video_ioctl2, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) .compat_ioctl = v4l_compat_ioctl32, -#endif .llseek = no_llseek, }; @@ -2368,9 +2366,7 @@ static const struct file_operations radio_fops = .open = video_open, .release = video_release, .ioctl = video_ioctl2, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) .compat_ioctl = v4l_compat_ioctl32, -#endif .llseek = no_llseek, }; diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h index 987c4338f..08bc1d0fa 100644 --- a/linux/drivers/media/video/saa7134/saa7134.h +++ b/linux/drivers/media/video/saa7134/saa7134.h @@ -41,12 +41,8 @@ #include <media/ir-common.h> #include <media/ir-kbd-i2c.h> #include <media/videobuf-dma-sg.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,64) -#include "i2c-compat.h" -#else #include <sound/core.h> #include <sound/pcm.h> -#endif #if defined(CONFIG_VIDEO_SAA7134_DVB) || defined(CONFIG_VIDEO_SAA7134_DVB_MODULE) #include <media/videobuf-dvb.h> #endif @@ -450,13 +446,11 @@ struct saa7134_dmasound { unsigned int read_offset; unsigned int read_count; void * priv_data; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16) snd_pcm_substream_t *substream; #else struct snd_pcm_substream *substream; #endif -#endif }; /* ts/mpeg status */ diff --git a/linux/drivers/media/video/saa717x.c b/linux/drivers/media/video/saa717x.c index adcc7adc5..a478bf25e 100644 --- a/linux/drivers/media/video/saa717x.c +++ b/linux/drivers/media/video/saa717x.c @@ -47,11 +47,7 @@ MODULE_AUTHOR("K. Ohta, T. Adachi, Hans Verkuil"); MODULE_LICENSE("GPL"); static int debug; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) module_param(debug, int, 0644); -#else -MODULE_PARM(debug, "i"); -#endif MODULE_PARM_DESC(debug, "Debug level (0-1)"); /* @@ -60,9 +56,6 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) static unsigned short normal_i2c[] = { 0x42 >> 1, I2C_CLIENT_END }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif I2C_CLIENT_INSMOD; #endif @@ -1535,13 +1528,8 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .command = saa717x_command, .probe = saa717x_probe, .remove = saa717x_remove, -#ifdef I2C_CLASS_TV_ANALOG .legacy_class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL, -#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) .id_table = saa717x_id, #endif }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -EXPORT_NO_SYMBOLS; -#endif diff --git a/linux/drivers/media/video/tda7432.c b/linux/drivers/media/video/tda7432.c index 5c58967ce..1305820d2 100644 --- a/linux/drivers/media/video/tda7432.c +++ b/linux/drivers/media/video/tda7432.c @@ -47,10 +47,6 @@ #include <linux/videodev.h> #include <linux/i2c.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include "i2c-compat.h" -#else -#endif #include <media/v4l2-common.h> #include <media/i2c-addr.h> #include "compat.h" @@ -77,9 +73,7 @@ static unsigned short normal_i2c[] = { I2C_ADDR_TDA7432 >> 1, I2C_CLIENT_END, }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif + I2C_CLIENT_INSMOD; /* Structure of address and subaddresses for the tda7432 */ @@ -314,12 +308,7 @@ static void do_tda7432_init(struct i2c_client *client) * i2c interface functions * * *********************** */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) static int tda7432_attach(struct i2c_adapter *adap, int addr, int kind) -#else -static int tda7432_attach(struct i2c_adapter *adap, int addr, - unsigned short flags, int kind) -#endif { struct tda7432 *t; struct i2c_client *client; @@ -335,9 +324,6 @@ static int tda7432_attach(struct i2c_adapter *adap, int addr, i2c_set_clientdata(client, t); do_tda7432_init(client); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - MOD_INC_USE_COUNT; -#endif i2c_attach_client(client); v4l_info(client, "chip found @ 0x%x (%s)\n", addr << 1, adap->name); @@ -346,13 +332,8 @@ static int tda7432_attach(struct i2c_adapter *adap, int addr, static int tda7432_probe(struct i2c_adapter *adap) { -#ifdef I2C_CLASS_TV_ANALOG if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, tda7432_attach); -#else - if (adap->id == I2C_HW_B_BT848) - return i2c_probe(adap, &addr_data, tda7432_attach); -#endif return 0; } @@ -364,9 +345,6 @@ static int tda7432_detach(struct i2c_client *client) i2c_detach_client(client); kfree(t); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - MOD_DEC_USE_COUNT; -#endif return 0; } @@ -531,10 +509,8 @@ static int tda7432_command(struct i2c_client *client, } static struct i2c_driver driver = { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))&&(LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)) +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) .owner = THIS_MODULE, -#endif -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) .name = "tda7432", .flags = I2C_DF_NOTIFY, #else diff --git a/linux/drivers/media/video/tda9840.c b/linux/drivers/media/video/tda9840.c index c41e50ba6..537a06492 100644 --- a/linux/drivers/media/video/tda9840.c +++ b/linux/drivers/media/video/tda9840.c @@ -51,9 +51,6 @@ MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); /* addresses to scan, found only at 0x42 (7-Bit) */ static unsigned short normal_i2c[] = { I2C_ADDR_TDA9840, I2C_CLIENT_END }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif /* magic definition of all other variables and things */ I2C_CLIENT_INSMOD; @@ -231,10 +228,8 @@ static int detach(struct i2c_client *client) } static struct i2c_driver driver = { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) &&(LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)) - .owner = THIS_MODULE, -#endif #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) + .owner = THIS_MODULE, .name = "tda9840", .flags = I2C_DF_NOTIFY, #else diff --git a/linux/drivers/media/video/tda9875.c b/linux/drivers/media/video/tda9875.c index 340ea2300..86e721656 100644 --- a/linux/drivers/media/video/tda9875.c +++ b/linux/drivers/media/video/tda9875.c @@ -31,11 +31,6 @@ #include <linux/init.h> #include "compat.h" -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include "id.h" -#include "i2c-compat.h" -#endif - #include <media/i2c-addr.h> static int debug; /* insmod parameter */ @@ -47,9 +42,7 @@ static unsigned short normal_i2c[] = { I2C_ADDR_TDA9875 >> 1, I2C_CLIENT_END }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif + I2C_CLIENT_INSMOD; /* This is a superset of the TDA9875 */ @@ -244,12 +237,7 @@ static int tda9875_checkit(struct i2c_adapter *adap, int addr) return(0); } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) static int tda9875_attach(struct i2c_adapter *adap, int addr, int kind) -#else -static int tda9875_attach(struct i2c_adapter *adap, int addr, - unsigned short flags, int kind) -#endif { struct tda9875 *t; struct i2c_client *client; @@ -271,9 +259,6 @@ static int tda9875_attach(struct i2c_adapter *adap, int addr, } do_tda9875_init(client); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - MOD_INC_USE_COUNT; -#endif printk(KERN_INFO "tda9875: init\n"); i2c_attach_client(client); @@ -282,13 +267,8 @@ static int tda9875_attach(struct i2c_adapter *adap, int addr, static int tda9875_probe(struct i2c_adapter *adap) { -#ifdef I2C_CLASS_TV_ANALOG if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, tda9875_attach); -#else - if (adap->id == I2C_HW_B_BT848) - return i2c_probe(adap, &addr_data, tda9875_attach); -#endif return 0; } @@ -300,9 +280,6 @@ static int tda9875_detach(struct i2c_client *client) i2c_detach_client(client); kfree(t); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - MOD_DEC_USE_COUNT; -#endif return 0; } @@ -456,10 +433,8 @@ static int tda9875_command(struct i2c_client *client, static struct i2c_driver driver = { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))&&(LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)) +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) .owner = THIS_MODULE, -#endif -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) .name = "tda9875", .flags = I2C_DF_NOTIFY, #else diff --git a/linux/drivers/media/video/tea6415c.c b/linux/drivers/media/video/tea6415c.c index 16f369195..cb700dde7 100644 --- a/linux/drivers/media/video/tea6415c.c +++ b/linux/drivers/media/video/tea6415c.c @@ -51,9 +51,6 @@ MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); /* addresses to scan, found only at 0x03 and/or 0x43 (7-bit) */ static unsigned short normal_i2c[] = { I2C_TEA6415C_1, I2C_TEA6415C_2, I2C_CLIENT_END }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif /* magic definition of all other variables and things */ I2C_CLIENT_INSMOD; @@ -200,10 +197,8 @@ static int command(struct i2c_client *client, unsigned int cmd, void *arg) } static struct i2c_driver driver = { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) &&(LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)) - .owner = THIS_MODULE, -#endif #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) + .owner = THIS_MODULE, .name = "tea6415c", .flags = I2C_DF_NOTIFY, #else diff --git a/linux/drivers/media/video/tea6420.c b/linux/drivers/media/video/tea6420.c index 7a8fec9cf..f1bba1568 100644 --- a/linux/drivers/media/video/tea6420.c +++ b/linux/drivers/media/video/tea6420.c @@ -48,9 +48,6 @@ MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); /* addresses to scan, found only at 0x4c and/or 0x4d (7-Bit) */ static unsigned short normal_i2c[] = { I2C_ADDR_TEA6420_1, I2C_ADDR_TEA6420_2, I2C_CLIENT_END }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif /* magic definition of all other variables and things */ I2C_CLIENT_INSMOD; @@ -176,10 +173,8 @@ static int command(struct i2c_client *client, unsigned int cmd, void *arg) } static struct i2c_driver driver = { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) &&(LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)) - .owner = THIS_MODULE, -#endif #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) + .owner = THIS_MODULE, .name = "tea6420", .flags = I2C_DF_NOTIFY, #else diff --git a/linux/drivers/media/video/tlv320aic23b.c b/linux/drivers/media/video/tlv320aic23b.c index 9f96e200c..b601c232a 100644 --- a/linux/drivers/media/video/tlv320aic23b.c +++ b/linux/drivers/media/video/tlv320aic23b.c @@ -32,10 +32,6 @@ #include <linux/videodev.h> #include <media/v4l2-common.h> #include <media/v4l2-i2c-drv-legacy.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -#include "i2c-compat.h" -#include <linux/slab.h> -#endif #include "compat.h" MODULE_DESCRIPTION("tlv320aic23b driver"); @@ -44,10 +40,6 @@ MODULE_LICENSE("GPL"); static unsigned short normal_i2c[] = { 0x34 >> 1, I2C_CLIENT_END }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif - I2C_CLIENT_INSMOD; /* ----------------------------------------------------------------------- */ @@ -175,9 +167,6 @@ static int tlv320aic23b_remove(struct i2c_client *client) } /* ----------------------------------------------------------------------- */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -EXPORT_NO_SYMBOLS; -#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) static const struct i2c_device_id tlv320aic23b_id[] = { diff --git a/linux/drivers/media/video/tuner-core.c b/linux/drivers/media/video/tuner-core.c index e0228b865..d80f7ee91 100644 --- a/linux/drivers/media/video/tuner-core.c +++ b/linux/drivers/media/video/tuner-core.c @@ -21,9 +21,6 @@ #include <media/tuner-types.h> #include <media/v4l2-common.h> #include <media/v4l2-i2c-drv-legacy.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include "i2c-compat.h" -#endif #include "mt20xx.h" #include "tda8290.h" #include "tea5761.h" @@ -114,9 +111,6 @@ static unsigned short normal_i2c[] = { I2C_CLIENT_END }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif I2C_CLIENT_INSMOD; /* insmod options used at init time => read/only */ @@ -162,17 +156,6 @@ static char secam[] = "--"; static char ntsc[] = "-"; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -MODULE_PARM(pal,"s"); -MODULE_PARM(secam,"s"); -MODULE_PARM(ntsc,"s"); -MODULE_PARM(tv_range,"2i"); -MODULE_PARM(radio_range,"2i"); -MODULE_PARM(no_autodetect, "i"); -MODULE_PARM(tuner_debug, "i"); -MODULE_PARM(addr, "i"); -MODULE_PARM(show_i2c, "i"); -#else module_param(addr, int, 0444); module_param(no_autodetect, int, 0444); module_param(show_i2c, int, 0444); @@ -180,15 +163,8 @@ module_param_named(debug,tuner_debug, int, 0644); module_param_string(pal, pal, sizeof(pal), 0644); module_param_string(secam, secam, sizeof(secam), 0644); module_param_string(ntsc, ntsc, sizeof(ntsc), 0644); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) -static unsigned int dummy; -module_param_array(tv_range, int, dummy, 0644); -module_param_array(radio_range, int, dummy, 0644); -#else module_param_array(tv_range, int, NULL, 0644); module_param_array(radio_range, int, NULL, 0644); -#endif -#endif MODULE_DESCRIPTION("device driver for various TV and TV+FM radio tuners"); MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer"); @@ -1280,11 +1256,7 @@ static int tuner_legacy_probe(struct i2c_adapter *adap) normal_i2c[1] = I2C_CLIENT_END; } -#ifdef I2C_CLASS_TV_ANALOG if ((adap->class & I2C_CLASS_TV_ANALOG) == 0) -#else - if (adap->id != I2C_HW_B_BT848) -#endif return 0; /* HACK: Ignore 0x6b and 0x6f on cx88 boards. @@ -1350,10 +1322,6 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { #endif }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -EXPORT_NO_SYMBOLS; -#endif - /* * Overrides for Emacs so that we follow Linus's tabbing style. * --------------------------------------------------------------------------- diff --git a/linux/drivers/media/video/tvaudio.c b/linux/drivers/media/video/tvaudio.c index 830dbe8db..84e2c43b7 100644 --- a/linux/drivers/media/video/tvaudio.c +++ b/linux/drivers/media/video/tvaudio.c @@ -31,10 +31,6 @@ #endif #include "compat.h" -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include "i2c-compat.h" -#else -#endif #include <media/tvaudio.h> #include <media/v4l2-common.h> #include <media/v4l2-chip-ident.h> @@ -151,9 +147,6 @@ static unsigned short normal_i2c[] = { I2C_ADDR_TDA9874 >> 1, I2C_ADDR_PIC16C54 >> 1, I2C_CLIENT_END }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif I2C_CLIENT_INSMOD; /* ---------------------------------------------------------------------- */ @@ -283,9 +276,7 @@ static int chip_thread(void *data) if (!kthread_should_stop()) schedule(); set_current_state(TASK_RUNNING); -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12) try_to_freeze(); -#endif if (kthread_should_stop()) break; v4l_dbg(1, debug, chip->c, "%s: thread wakeup\n", chip->c->name); @@ -1847,19 +1838,8 @@ static int chip_legacy_probe(struct i2c_adapter *adap) because dedicated drivers are used */ if ((adap->id == I2C_HW_SAA7146)) return 0; -#ifdef I2C_CLASS_TV_ANALOG if (adap->class & I2C_CLASS_TV_ANALOG) return 1; -#else - switch (adap->id) { - case I2C_HW_B_BT848: - case I2C_HW_B_RIVA: -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - case I2C_HW_SAA7134: -#endif - return 1; - } -#endif return 0; } diff --git a/linux/drivers/media/video/tveeprom.c b/linux/drivers/media/video/tveeprom.c index e38bda67a..dc0bd9fda 100644 --- a/linux/drivers/media/video/tveeprom.c +++ b/linux/drivers/media/video/tveeprom.c @@ -36,9 +36,6 @@ #include <linux/types.h> #include <linux/videodev.h> #include <linux/i2c.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -#include <linux/slab.h> -#endif #include <media/tuner.h> #include <media/tveeprom.h> diff --git a/linux/drivers/media/video/tvmixer.c b/linux/drivers/media/video/tvmixer.c index ca7330e10..2862efa93 100644 --- a/linux/drivers/media/video/tvmixer.c +++ b/linux/drivers/media/video/tvmixer.c @@ -19,16 +19,6 @@ #include <asm/semaphore.h> #include <asm/uaccess.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -# include "i2c-compat.h" -#endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,71) -# define strlcpy(dest,src,len) strncpy(dest,src,(len)-1) -#endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -# define iminor(inode) minor(inode->i_rdev) -#endif - #define DEV_MAX 4 static int devnr = -1; @@ -206,14 +196,8 @@ static int tvmixer_open(struct inode *inode, struct file *file) /* lock bttv in memory while the mixer is in use */ file->private_data = mix; -#ifndef I2C_PEC - if (client->adapter->inc_use) - client->adapter->inc_use(client->adapter); -#endif -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,54) if (client->adapter->owner) try_module_get(client->adapter->owner); -#endif return 0; } @@ -227,21 +211,13 @@ static int tvmixer_release(struct inode *inode, struct file *file) return -ENODEV; } -#ifndef I2C_PEC - if (client->adapter->dec_use) - client->adapter->dec_use(client->adapter); -#endif -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,54) module_put(client->adapter->owner); -#endif return 0; } static struct i2c_driver driver = { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))&&(LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)) - .owner = THIS_MODULE, -#endif #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) + .owner = THIS_MODULE, .name = "tvmixer", .flags = I2C_DF_NOTIFY, #else @@ -269,20 +245,10 @@ static const struct file_operations tvmixer_fops = { static int tvmixer_adapters(struct i2c_adapter *adap) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,54) struct i2c_client *client; list_for_each_entry(client, &adap->clients, list) tvmixer_clients(client); -#else - int i; - - for (i=0; i<I2C_CLIENT_MAX; i++) { - if (!adap->clients[i]) - continue; - tvmixer_clients(adap->clients[i]); - } -#endif return 0; } @@ -291,22 +257,8 @@ static int tvmixer_clients(struct i2c_client *client) struct video_audio va; int i,minor; -#ifdef I2C_CLASS_TV_ANALOG if (!(client->adapter->class & I2C_CLASS_TV_ANALOG)) return -1; -#else - /* TV card ??? */ - switch (client->adapter->id) { - case I2C_HW_SMBUS_VOODOO3: - case I2C_HW_B_BT848: - case I2C_HW_B_RIVA: - /* ok, have a look ... */ - break; - default: - /* ignore that one */ - return -1; - } -#endif /* unregister ?? */ for (i = 0; i < DEV_MAX; i++) { diff --git a/linux/drivers/media/video/tvp5150.c b/linux/drivers/media/video/tvp5150.c index 7dc6623cc..3c0e2b316 100644 --- a/linux/drivers/media/video/tvp5150.c +++ b/linux/drivers/media/video/tvp5150.c @@ -12,12 +12,6 @@ #include <linux/video_decoder.h> #include <media/v4l2-common.h> #include <media/tvp5150.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/slab.h> -#include "i2c-compat.h" -#endif #include "tvp5150_reg.h" @@ -32,9 +26,6 @@ static unsigned short normal_i2c[] = { I2C_CLIENT_END }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif I2C_CLIENT_INSMOD; static int debug; @@ -1148,13 +1139,8 @@ static struct i2c_client client_template = { .driver = &driver, }; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) static int tvp5150_detect_client(struct i2c_adapter *adapter, int address, int kind) -#else -static int tvp5150_detect_client(struct i2c_adapter *adapter, - int address, unsigned short flags, int kind) -#endif { struct i2c_client *c; struct tvp5150 *core; @@ -1204,9 +1190,6 @@ static int tvp5150_detect_client(struct i2c_adapter *adapter, if (debug > 1) dump_reg(c); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - MOD_INC_USE_COUNT; -#endif return 0; } @@ -1242,10 +1225,8 @@ static int tvp5150_detach_client(struct i2c_client *c) /* ----------------------------------------------------------------------- */ static struct i2c_driver driver = { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))&&(LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)) +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) .owner = THIS_MODULE, -#endif -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) .name = "tvp5150", .flags = I2C_DF_NOTIFY, #else diff --git a/linux/drivers/media/video/upd64031a.c b/linux/drivers/media/video/upd64031a.c index c59944d72..dfca5ed6e 100644 --- a/linux/drivers/media/video/upd64031a.c +++ b/linux/drivers/media/video/upd64031a.c @@ -46,21 +46,13 @@ MODULE_AUTHOR("T. Adachi, Takeru KOMORIYA, Hans Verkuil"); MODULE_LICENSE("GPL"); static int debug; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) module_param(debug, int, 0644); -#else -MODULE_PARM(debug, "i"); -#endif MODULE_PARM_DESC(debug, "Debug level (0-1)"); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) static unsigned short normal_i2c[] = { 0x24 >> 1, 0x26 >> 1, I2C_CLIENT_END }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif - I2C_CLIENT_INSMOD; #endif @@ -241,9 +233,6 @@ static int upd64031a_remove(struct i2c_client *client) } /* ----------------------------------------------------------------------- */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) -EXPORT_NO_SYMBOLS; -#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) static const struct i2c_device_id upd64031a_id[] = { diff --git a/linux/drivers/media/video/upd64083.c b/linux/drivers/media/video/upd64083.c index 3dcc5a293..5f0c6919d 100644 --- a/linux/drivers/media/video/upd64083.c +++ b/linux/drivers/media/video/upd64083.c @@ -37,21 +37,13 @@ MODULE_AUTHOR("T. Adachi, Takeru KOMORIYA, Hans Verkuil"); MODULE_LICENSE("GPL"); static int debug; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) module_param(debug, bool, 0644); -#else -MODULE_PARM(debug, "i"); -#endif MODULE_PARM_DESC(debug, "Debug level (0-1)"); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) static unsigned short normal_i2c[] = { 0xb8 >> 1, 0xba >> 1, I2C_CLIENT_END }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif - I2C_CLIENT_INSMOD; #endif @@ -218,9 +210,6 @@ static int upd64083_remove(struct i2c_client *client) } /* ----------------------------------------------------------------------- */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) -EXPORT_NO_SYMBOLS; -#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) static const struct i2c_device_id upd64083_id[] = { diff --git a/linux/drivers/media/video/usbvideo/konicawc.c b/linux/drivers/media/video/usbvideo/konicawc.c index 7e2f04fb4..6fef59557 100644 --- a/linux/drivers/media/video/usbvideo/konicawc.c +++ b/linux/drivers/media/video/usbvideo/konicawc.c @@ -17,10 +17,8 @@ #include <linux/init.h> #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) #include <linux/usb/input.h> -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13) -#include <linux/usb_input.h> #else -#include <linux/input.h> +#include <linux/usb_input.h> #endif #include "usbvideo.h" diff --git a/linux/drivers/media/video/usbvideo/quickcam_messenger.c b/linux/drivers/media/video/usbvideo/quickcam_messenger.c index a4f1185c0..69f0fc770 100644 --- a/linux/drivers/media/video/usbvideo/quickcam_messenger.c +++ b/linux/drivers/media/video/usbvideo/quickcam_messenger.c @@ -35,7 +35,7 @@ #include <linux/input.h> #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) #include <linux/usb/input.h> -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13) +#else #include <linux/usb_input.h> #endif diff --git a/linux/drivers/media/video/usbvision/usbvision-core.c b/linux/drivers/media/video/usbvision/usbvision-core.c index ce9348a07..bf464540c 100644 --- a/linux/drivers/media/video/usbvision/usbvision-core.c +++ b/linux/drivers/media/video/usbvision/usbvision-core.c @@ -45,13 +45,7 @@ #include <media/tuner.h> #include <media/audiochip.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -#include <linux/proc_fs.h> -#include <linux/tqueue.h> -#include <linux/wrapper.h> -#else #include <linux/workqueue.h> -#endif #ifdef CONFIG_KMOD #include <linux/kmod.h> @@ -174,40 +168,6 @@ static void usbvision_rvfree(void *mem, unsigned long size) vfree(mem); } -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,24) -/* helper functions to access driver private data. */ -static inline void *video_get_drvdata(struct video_device *dev) -{ - return dev->priv; -} - -static inline void video_set_drvdata(struct video_device *dev, void *data) -{ - dev->priv = data; -} - -struct video_device *video_device_alloc(void) -{ - struct video_device *vfd; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) - vfd = kmalloc(sizeof(*vfd),GFP_KERNEL); - if (NULL == vfd) - return NULL; - memset(vfd,0,sizeof(*vfd)); -#else - vfd = kzalloc(sizeof(*vfd),GFP_KERNEL); - if (NULL == vfd) - return NULL; -#endif - return vfd; -} - -void video_device_release(struct video_device *vfd) -{ - kfree(vfd); -} -#endif - #if ENABLE_HEXDUMP static void usbvision_hexdump(const unsigned char *data, int len) @@ -1485,7 +1445,7 @@ static int usbvision_compress_isochronous(struct usb_usbvision *usbvision, return totlen; } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) || LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) static void usbvision_isocIrq(struct urb *urb) { #else @@ -1559,7 +1519,6 @@ static void usbvision_isocIrq(struct urb *urb, struct pt_regs *regs) urb->iso_frame_desc[i].actual_length = 0; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) urb->status = 0; urb->dev = usbvision->dev; errCode = usb_submit_urb (urb, GFP_ATOMIC); @@ -1568,7 +1527,6 @@ static void usbvision_isocIrq(struct urb *urb, struct pt_regs *regs) err("%s: usb_submit_urb failed: error %d", __func__, errCode); } -#endif return; } @@ -1632,7 +1590,7 @@ int usbvision_write_reg(struct usb_usbvision *usbvision, unsigned char reg, } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) || LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) static void usbvision_ctrlUrb_complete(struct urb *urb) #else static void usbvision_ctrlUrb_complete(struct urb *urb, struct pt_regs *regs) @@ -1662,19 +1620,11 @@ static int usbvision_write_reg_irq(struct usb_usbvision *usbvision,int address, } usbvision->ctrlUrbBusy = 1; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20) - usbvision->ctrlUrbSetup.requesttype = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT; - usbvision->ctrlUrbSetup.request = USBVISION_OP_CODE; - usbvision->ctrlUrbSetup.value = 0; - usbvision->ctrlUrbSetup.index = cpu_to_le16(address); - usbvision->ctrlUrbSetup.length = cpu_to_le16(len); -#else usbvision->ctrlUrbSetup.bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT; usbvision->ctrlUrbSetup.bRequest = USBVISION_OP_CODE; usbvision->ctrlUrbSetup.wValue = 0; usbvision->ctrlUrbSetup.wIndex = cpu_to_le16(address); usbvision->ctrlUrbSetup.wLength = cpu_to_le16(len); -#endif usb_fill_control_urb (usbvision->ctrlUrb, usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1), (unsigned char *)&usbvision->ctrlUrbSetup, @@ -1684,11 +1634,7 @@ static int usbvision_write_reg_irq(struct usb_usbvision *usbvision,int address, memcpy(usbvision->ctrlUrbBuffer, data, len); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - errCode = usb_submit_urb(usbvision->ctrlUrb); -#else errCode = usb_submit_urb(usbvision->ctrlUrb, GFP_ATOMIC); -#endif if (errCode < 0) { // error in usb_submit_urb() usbvision->ctrlUrbBusy = 0; @@ -2385,18 +2331,12 @@ static void usbvision_powerOffTimer(unsigned long data) PDEBUG(DBG_FUNC, ""); del_timer(&usbvision->powerOffTimer); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - INIT_TQUEUE(&usbvision->powerOffTask, call_usbvision_power_off, usbvision); - (void) schedule_task(&usbvision->powerOffTask); -#else #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) INIT_WORK(&usbvision->powerOffWork, call_usbvision_power_off, usbvision); #else INIT_WORK(&usbvision->powerOffWork, call_usbvision_power_off); #endif (void) schedule_work(&usbvision->powerOffWork); -#endif - } void usbvision_init_powerOffTimer(struct usb_usbvision *usbvision) @@ -2568,11 +2508,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) int j, k; struct urb *urb; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - urb = usb_alloc_urb(USBVISION_URB_FRAMES); -#else urb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL); -#endif if (urb == NULL) { err("%s: usb_alloc_urb() failed", __func__); return -ENOMEM; @@ -2586,12 +2522,8 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) urb->dev = dev; urb->context = usbvision; urb->pipe = usb_rcvisocpipe(dev, usbvision->video_endp); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - urb->transfer_flags = USB_ISO_ASAP; -#else urb->transfer_flags = URB_ISO_ASAP; urb->interval = 1; -#endif urb->transfer_buffer = usbvision->sbuf[bufIdx].data; urb->complete = usbvision_isocIrq; urb->number_of_packets = USBVISION_URB_FRAMES; @@ -2605,28 +2537,10 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) } } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - /* Link URBs into a ring so that they invoke each other infinitely */ - for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) { - if ((bufIdx + 1) < USBVISION_NUMSBUF) { - usbvision->sbuf[bufIdx].urb->next = - usbvision->sbuf[bufIdx + 1].urb; - } - else { - usbvision->sbuf[bufIdx].urb->next = - usbvision->sbuf[0].urb; - } - } -#endif - /* Submit all URBs */ for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) { - #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb); - #else errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb, GFP_KERNEL); - #endif if (errCode) { err("%s: usb_submit_urb(%d) failed: error %d", __func__, bufIdx, errCode); @@ -2656,7 +2570,6 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision) return; /* Unschedule all of the iso td's */ -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9) for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) { usb_kill_urb(usbvision->sbuf[bufIdx].urb); if (usbvision->sbuf[bufIdx].data){ @@ -2668,25 +2581,6 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision) usb_free_urb(usbvision->sbuf[bufIdx].urb); usbvision->sbuf[bufIdx].urb = NULL; } -#else - for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) { - errCode = usb_unlink_urb(usbvision->sbuf[bufIdx].urb); - if (errCode < 0) - err("%s: usb_unlink_urb() failed: error %d", - __func__, errCode); - } - - if (usbvision->sbuf[bufIdx].data){ - usb_buffer_free(usbvision->dev, - sb_size, - usbvision->sbuf[bufIdx].data, - usbvision->sbuf[bufIdx].urb->transfer_dma); - } - /* Delete them all */ - for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) - usb_free_urb(usbvision->sbuf[bufIdx].urb); -#endif - PDEBUG(DBG_ISOC, "%s: streaming=Stream_Off\n", __func__); usbvision->streaming = Stream_Off; diff --git a/linux/drivers/media/video/usbvision/usbvision-i2c.c b/linux/drivers/media/video/usbvision/usbvision-i2c.c index 67efd7821..1b6180573 100644 --- a/linux/drivers/media/video/usbvision/usbvision-i2c.c +++ b/linux/drivers/media/video/usbvision/usbvision-i2c.c @@ -193,28 +193,9 @@ static u32 functionality(struct i2c_adapter *adap) return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR; } -#ifndef I2C_PEC -static void inc_use(struct i2c_adapter *adap) -{ - MOD_INC_USE_COUNT; -} - -static void dec_use(struct i2c_adapter *adap) -{ - MOD_DEC_USE_COUNT; -} -#endif - /* -----exported algorithm data: ------------------------------------- */ static struct i2c_algorithm usbvision_algo = { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,30)) - .owner = THIS_MODULE, -#endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) - .name = "USB algorithm", - .id = I2C_ALGO_BIT, /* FIXME */ -#endif .master_xfer = usbvision_i2c_xfer, .smbus_xfer = NULL, .functionality = functionality, @@ -231,9 +212,6 @@ static int usbvision_i2c_usb_add_bus(struct i2c_adapter *adap) /* register new adapter to i2c module... */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) - adap->id |= usbvision_algo.id; -#endif adap->algo = &usbvision_algo; adap->timeout = 100; /* default values, should */ @@ -533,30 +511,16 @@ static int usbvision_i2c_read(struct usb_usbvision *usbvision, unsigned char add } static struct i2c_adapter i2c_adap_template = { -#ifdef I2C_PEC .owner = THIS_MODULE, -#else - .inc_use = inc_use, - .dec_use = dec_use, -#endif .name = "usbvision", .id = I2C_HW_B_BT848, /* FIXME */ .client_register = attach_inform, .client_unregister = detach_inform, -#ifdef I2C_ADAP_CLASS_TV_ANALOG - .class = I2C_ADAP_CLASS_TV_ANALOG, -#else -#ifdef I2C_CLASS_TV_ANALOG .class = I2C_CLASS_TV_ANALOG, -#endif -#endif }; static struct i2c_client i2c_client_template = { .name = "usbvision internal", -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) - .id = -1, -#endif #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) .flags = I2C_CLIENT_ALLOW_USE, #endif diff --git a/linux/drivers/media/video/usbvision/usbvision-video.c b/linux/drivers/media/video/usbvision/usbvision-video.c index 55b3f5e60..073d30454 100644 --- a/linux/drivers/media/video/usbvision/usbvision-video.c +++ b/linux/drivers/media/video/usbvision/usbvision-video.c @@ -68,13 +68,7 @@ #include <media/tuner.h> #include <media/audiochip.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -#include <linux/proc_fs.h> -#include <linux/tqueue.h> -#include <linux/wrapper.h> -#else #include <linux/workqueue.h> -#endif #ifdef CONFIG_KMOD #include <linux/kmod.h> @@ -173,10 +167,8 @@ MODULE_PARM_DESC(vbi_nr, "Set vbi device number (/dev/vbiX). Default: -1 (autod MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE(DRIVER_LICENSE); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) MODULE_VERSION(USBVISION_VERSION_STRING); MODULE_ALIAS(DRIVER_ALIAS); -#endif /*****************************************************************************/ @@ -187,8 +179,6 @@ MODULE_ALIAS(DRIVER_ALIAS); /* /sys/bus/usb/drivers/USBVision Video Grabber */ /*****************************************************************************/ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) - #define YES_NO(x) ((x) ? "Yes" : "No") static inline struct usb_usbvision *cd_to_usbvision(struct device *cd) @@ -379,8 +369,6 @@ static void usbvision_remove_sysfs(struct video_device *vdev) } } -#endif - /* * usbvision_open() * @@ -389,25 +377,15 @@ static void usbvision_remove_sysfs(struct video_device *vdev) * then allocates buffers needed for video processing. * */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19) -static int usbvision_v4l2_open(struct video_device *dev, int flags) -{ - struct usb_usbvision *usbvision = (struct usb_usbvision *) dev; -#else static int usbvision_v4l2_open(struct inode *inode, struct file *file) { struct video_device *dev = video_devdata(file); struct usb_usbvision *usbvision = (struct usb_usbvision *) video_get_drvdata(dev); -#endif int errCode = 0; PDEBUG(DBG_IO, "open"); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - MOD_INC_USE_COUNT; -#endif - usbvision_reset_powerOffTimer(usbvision); if (usbvision->user) @@ -461,12 +439,6 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file) mutex_unlock(&usbvision->lock); } - if (errCode) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - MOD_DEC_USE_COUNT; -#endif - } - /* prepare queues */ usbvision_empty_framequeues(usbvision); @@ -482,17 +454,11 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file) * allocated in usbvision_v4l2_open(). * */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19) -static void usbvision_v4l2_close(struct video_device *dev) -{ - struct usb_usbvision *usbvision = (struct usb_usbvision *) dev; -#else static int usbvision_v4l2_close(struct inode *inode, struct file *file) { struct video_device *dev = video_devdata(file); struct usb_usbvision *usbvision = (struct usb_usbvision *) video_get_drvdata(dev); -#endif PDEBUG(DBG_IO, "close"); mutex_lock(&usbvision->lock); @@ -523,14 +489,7 @@ static int usbvision_v4l2_close(struct inode *inode, struct file *file) } PDEBUG(DBG_IO, "success"); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - MOD_DEC_USE_COUNT; -#endif - - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19) return 0; -#endif } @@ -1123,12 +1082,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, return 0; } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19) -static long usbvision_v4l2_read(struct video_device *dev, char *buf, - unsigned long count, int noblock) -{ - struct usb_usbvision *usbvision = (struct usb_usbvision *) dev; -#else static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { @@ -1136,7 +1089,6 @@ static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf, struct usb_usbvision *usbvision = (struct usb_usbvision *) video_get_drvdata(dev); int noblock = file->f_flags & O_NONBLOCK; -#endif unsigned long lock_flags; int ret,i; @@ -1302,24 +1254,15 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma) * Here comes the stuff for radio on usbvision based devices * */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19) -static int usbvision_radio_open(struct video_device *dev, int flags) -{ - struct usb_usbvision *usbvision = (struct usb_usbvision *)dev->priv; -#else static int usbvision_radio_open(struct inode *inode, struct file *file) { struct video_device *dev = video_devdata(file); struct usb_usbvision *usbvision = (struct usb_usbvision *) video_get_drvdata(dev); -#endif int errCode = 0; PDEBUG(DBG_IO, "%s:", __func__); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - MOD_INC_USE_COUNT; -#endif mutex_lock(&usbvision->lock); if (usbvision->user) { @@ -1351,9 +1294,6 @@ static int usbvision_radio_open(struct inode *inode, struct file *file) } if (errCode) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - MOD_DEC_USE_COUNT; -#endif if (PowerOnAtOpen) { usbvision_i2c_unregister(usbvision); usbvision_power_off(usbvision); @@ -1366,18 +1306,12 @@ out: } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19) -static void usbvision_radio_close(struct video_device *dev) -{ - struct usb_usbvision *usbvision = (struct usb_usbvision *)dev->priv; -#else static int usbvision_radio_close(struct inode *inode, struct file *file) { struct video_device *dev = video_devdata(file); struct usb_usbvision *usbvision = (struct usb_usbvision *) video_get_drvdata(dev); int errCode = 0; -#endif PDEBUG(DBG_IO, ""); @@ -1404,42 +1338,22 @@ static int usbvision_radio_close(struct inode *inode, struct file *file) usbvision_release(usbvision); } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - MOD_DEC_USE_COUNT; -#endif - PDEBUG(DBG_IO, "success"); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19) return errCode; -#endif } /* * Here comes the stuff for vbi on usbvision based devices * */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19) -static int usbvision_vbi_open(struct video_device *dev, int flags) -{ - struct usb_usbvision *usbvision = (struct usb_usbvision *)dev->priv; -#else static int usbvision_vbi_open(struct inode *inode, struct file *file) { -#endif /* TODO */ return -ENODEV; - } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19) -static void usbvision_vbi_close(struct video_device *dev) -{ - struct usb_usbvision *usbvision = (struct usb_usbvision *)dev->priv; -#else static int usbvision_vbi_close(struct inode *inode, struct file *file) { -#endif /* TODO */ return -ENODEV; } @@ -1463,21 +1377,8 @@ static int usbvision_vbi_ioctl(struct inode *inode, struct file *file, // // Video template -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19) -static struct video_device usbvision_video_template = { - .type = VID_TYPE_TUNER | VID_TYPE_CAPTURE, - .open = usbvision_v4l2_open, - .close = usbvision_v4l2_close, - .read = usbvision_v4l2_read, - .mmap = usbvision_v4l2_mmap, - .ioctl = video_ioctl2, - .minor = -1, -}; -#else static const struct file_operations usbvision_fops = { -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,31) .owner = THIS_MODULE, -#endif .open = usbvision_v4l2_open, .release = usbvision_v4l2_close, .read = usbvision_v4l2_read, @@ -1485,20 +1386,14 @@ static const struct file_operations usbvision_fops = { .ioctl = video_ioctl2, .llseek = no_llseek, /* .poll = video_poll, */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) .compat_ioctl = v4l_compat_ioctl32, -#endif }; static struct video_device usbvision_video_template = { -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,31) .owner = THIS_MODULE, -#endif .type = VID_TYPE_TUNER | VID_TYPE_CAPTURE, .fops = &usbvision_fops, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) .name = "usbvision-video", .release = video_device_release, -#endif .minor = -1, .vidioc_querycap = vidioc_querycap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, @@ -1534,44 +1429,25 @@ static struct video_device usbvision_video_template = { .tvnorms = USBVISION_NORMS, .current_norm = V4L2_STD_PAL }; -#endif // Radio template -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19) -static struct video_device usbvision_radio_template= -{ - .type = VID_TYPE_TUNER, - .open = usbvision_radio_open, - .close = usbvision_radio_close, - .ioctl = video_ioctl2, - .minor -1, -}; -#else static const struct file_operations usbvision_radio_fops = { -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,31) .owner = THIS_MODULE, -#endif .open = usbvision_radio_open, .release = usbvision_radio_close, .ioctl = video_ioctl2, .llseek = no_llseek, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) .compat_ioctl = v4l_compat_ioctl32, -#endif }; static struct video_device usbvision_radio_template= { -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,31) .owner = THIS_MODULE, -#endif .type = VID_TYPE_TUNER, .fops = &usbvision_radio_fops, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) .name = "usbvision-radio", .release = video_device_release, -#endif .minor = -1, .vidioc_querycap = vidioc_querycap, .vidioc_enum_input = vidioc_enum_input, @@ -1590,46 +1466,26 @@ static struct video_device usbvision_radio_template= .tvnorms = USBVISION_NORMS, .current_norm = V4L2_STD_PAL }; -#endif // vbi template -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19) -static struct video_device usbvision_vbi_template= -{ - type: VID_TYPE_TELETEXT, - open: usbvision_vbi_open, - close: usbvision_vbi_close, - ioctl: usbvision_vbi_ioctl, - minor: -1, -}; -#else static const struct file_operations usbvision_vbi_fops = { -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,31) .owner = THIS_MODULE, -#endif .open = usbvision_vbi_open, .release = usbvision_vbi_close, .ioctl = usbvision_vbi_ioctl, .llseek = no_llseek, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) .compat_ioctl = v4l_compat_ioctl32, -#endif }; static struct video_device usbvision_vbi_template= { -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,31) .owner = THIS_MODULE, -#endif .type = VID_TYPE_TUNER, .fops = &usbvision_vbi_fops, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) .release = video_device_release, .name = "usbvision-vbi", -#endif .minor = -1, }; -#endif static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision, @@ -1650,9 +1506,7 @@ static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision, } *vdev = *vdev_template; // vdev->minor = -1; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) vdev->dev = &usb_dev->dev; -#endif snprintf(vdev->name, sizeof(vdev->name), "%s", name); video_set_drvdata(vdev, usbvision); return vdev; @@ -1667,9 +1521,6 @@ static void usbvision_unregister_video(struct usb_usbvision *usbvision) usbvision->vbi->minor & 0x1f); if (usbvision->vbi->minor != -1) { video_unregister_device(usbvision->vbi); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - video_device_release(usbvision->vbi); -#endif } else { video_device_release(usbvision->vbi); } @@ -1682,9 +1533,6 @@ static void usbvision_unregister_video(struct usb_usbvision *usbvision) usbvision->rdev->minor & 0x1f); if (usbvision->rdev->minor != -1) { video_unregister_device(usbvision->rdev); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - video_device_release(usbvision->rdev); -#endif } else { video_device_release(usbvision->rdev); } @@ -1697,9 +1545,6 @@ static void usbvision_unregister_video(struct usb_usbvision *usbvision) usbvision->vdev->minor & 0x1f); if (usbvision->vdev->minor != -1) { video_unregister_device(usbvision->vdev); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - video_device_release(usbvision->vdev); -#endif } else { video_device_release(usbvision->vdev); } @@ -1799,11 +1644,7 @@ static struct usb_usbvision *usbvision_alloc(struct usb_device *dev) mutex_init(&usbvision->lock); /* available */ // prepare control urb for control messages during interrupts -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - usbvision->ctrlUrb = usb_alloc_urb(USBVISION_URB_FRAMES); -#else usbvision->ctrlUrb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL); -#endif if (usbvision->ctrlUrb == NULL) { goto err_exit; } @@ -2006,12 +1847,7 @@ static int __devinit usbvision_probe(struct usb_interface *intf, usbvision_create_sysfs(usbvision->vdev); PDEBUG(DBG_PROBE, "success"); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - MOD_DEC_USE_COUNT; - return usbvision; -#else return 0; -#endif } @@ -2023,15 +1859,9 @@ static int __devinit usbvision_probe(struct usb_interface *intf, * with no ill consequences. * */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -static void usbvision_disconnect(struct usb_device *dev, void *ptr) -{ - struct usb_usbvision *usbvision = (struct usb_usbvision *) ptr; -#else static void __devexit usbvision_disconnect(struct usb_interface *intf) { struct usb_usbvision *usbvision = usb_get_intfdata(intf); -#endif PDEBUG(DBG_PROBE, ""); @@ -2039,11 +1869,7 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf) err("%s: usb_get_intfdata() failed", __func__); return; } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - MOD_INC_USE_COUNT; -#else usb_set_intfdata (intf, NULL); -#endif mutex_lock(&usbvision->lock); @@ -2056,9 +1882,7 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf) } usbvision->remove_pending = 1; // Now all ISO data will be ignored -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) usb_put_dev(usbvision->dev); -#endif usbvision->dev = NULL; // USB device is no more mutex_unlock(&usbvision->lock); @@ -2073,15 +1897,10 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf) } PDEBUG(DBG_PROBE, "success"); - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - MOD_DEC_USE_COUNT; -#endif } static struct usb_driver usbvision_driver = { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,31)) && \ - (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16) .owner = THIS_MODULE, #endif .name = "usbvision", diff --git a/linux/drivers/media/video/usbvision/usbvision.h b/linux/drivers/media/video/usbvision/usbvision.h index 9f4c40dbf..371c6987f 100644 --- a/linux/drivers/media/video/usbvision/usbvision.h +++ b/linux/drivers/media/video/usbvision/usbvision.h @@ -401,11 +401,7 @@ struct usb_usbvision { struct semaphore lock; #endif struct timer_list powerOffTimer; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - struct tq_struct powerOffTask; -#else struct work_struct powerOffWork; -#endif int power; /* is the device powered on? */ int user; /* user count for exclusive use */ int initialized; /* Had we already sent init sequence? */ diff --git a/linux/drivers/media/video/uvc/uvc_driver.c b/linux/drivers/media/video/uvc/uvc_driver.c index e7b469ca5..31a0e706a 100644 --- a/linux/drivers/media/video/uvc/uvc_driver.c +++ b/linux/drivers/media/video/uvc/uvc_driver.c @@ -298,7 +298,8 @@ static int uvc_parse_format(struct uvc_device *dev, switch (buffer[2]) { case VS_FORMAT_UNCOMPRESSED: case VS_FORMAT_FRAME_BASED: - if (buflen < 27) { + n = buffer[2] == VS_FORMAT_UNCOMPRESSED ? 27 : 28; + if (buflen < n) { uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" "interface %d FORMAT error\n", dev->udev->devnum, diff --git a/linux/drivers/media/video/uvc/uvc_status.c b/linux/drivers/media/video/uvc/uvc_status.c index f401c44bd..7bfddad37 100644 --- a/linux/drivers/media/video/uvc/uvc_status.c +++ b/linux/drivers/media/video/uvc/uvc_status.c @@ -203,6 +203,6 @@ int uvc_status_resume(struct uvc_device *dev) if (dev->int_urb == NULL) return 0; - return usb_submit_urb(dev->int_urb, GFP_KERNEL); + return usb_submit_urb(dev->int_urb, GFP_NOIO); } diff --git a/linux/drivers/media/video/uvc/uvc_video.c b/linux/drivers/media/video/uvc/uvc_video.c index 83600f259..ad63794fd 100644 --- a/linux/drivers/media/video/uvc/uvc_video.c +++ b/linux/drivers/media/video/uvc/uvc_video.c @@ -554,9 +554,56 @@ static void uvc_video_complete(struct urb *urb) } /* + * Free transfer buffers. + */ +static void uvc_free_urb_buffers(struct uvc_video_device *video) +{ + unsigned int i; + + for (i = 0; i < UVC_URBS; ++i) { + if (video->urb_buffer[i]) { + usb_buffer_free(video->dev->udev, video->urb_size, + video->urb_buffer[i], video->urb_dma[i]); + video->urb_buffer[i] = NULL; + } + } + + video->urb_size = 0; +} + +/* + * Allocate transfer buffers. This function can be called with buffers + * already allocated when resuming from suspend, in which case it will + * return without touching the buffers. + * + * Return 0 on success or -ENOMEM when out of memory. + */ +static int uvc_alloc_urb_buffers(struct uvc_video_device *video, + unsigned int size) +{ + unsigned int i; + + /* Buffers are already allocated, bail out. */ + if (video->urb_size) + return 0; + + for (i = 0; i < UVC_URBS; ++i) { + video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev, + size, GFP_KERNEL, &video->urb_dma[i]); + if (video->urb_buffer[i] == NULL) { + uvc_free_urb_buffers(video); + return -ENOMEM; + } + } + + video->urb_size = size; + return 0; +} + +/* * Uninitialize isochronous/bulk URBs and free transfer buffers. */ -static void uvc_uninit_video(struct uvc_video_device *video) +static void uvc_uninit_video(struct uvc_video_device *video, int free_buffers) { struct urb *urb; unsigned int i; @@ -566,19 +613,12 @@ static void uvc_uninit_video(struct uvc_video_device *video) continue; usb_kill_urb(urb); - /* urb->transfer_buffer_length is not touched by USB core, so - * we can use it here as the buffer length. - */ - if (video->urb_buffer[i]) { - usb_buffer_free(video->dev->udev, - urb->transfer_buffer_length, - video->urb_buffer[i], urb->transfer_dma); - video->urb_buffer[i] = NULL; - } - usb_free_urb(urb); video->urb[i] = NULL; } + + if (free_buffers) + uvc_free_urb_buffers(video); } /* @@ -586,7 +626,7 @@ static void uvc_uninit_video(struct uvc_video_device *video) * is given by the endpoint. */ static int uvc_init_video_isoc(struct uvc_video_device *video, - struct usb_host_endpoint *ep) + struct usb_host_endpoint *ep, gfp_t gfp_flags) { struct urb *urb; unsigned int npackets, i, j; @@ -610,18 +650,13 @@ static int uvc_init_video_isoc(struct uvc_video_device *video, size = npackets * psize; + if (uvc_alloc_urb_buffers(video, size) < 0) + return -ENOMEM; + for (i = 0; i < UVC_URBS; ++i) { - urb = usb_alloc_urb(npackets, GFP_KERNEL); + urb = usb_alloc_urb(npackets, gfp_flags); if (urb == NULL) { - uvc_uninit_video(video); - return -ENOMEM; - } - - video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev, - size, GFP_KERNEL, &urb->transfer_dma); - if (video->urb_buffer[i] == NULL) { - usb_free_urb(urb); - uvc_uninit_video(video); + uvc_uninit_video(video, 1); return -ENOMEM; } @@ -632,6 +667,7 @@ static int uvc_init_video_isoc(struct uvc_video_device *video, urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; urb->interval = ep->desc.bInterval; urb->transfer_buffer = video->urb_buffer[i]; + urb->transfer_dma = video->urb_dma[i]; urb->complete = uvc_video_complete; urb->number_of_packets = npackets; urb->transfer_buffer_length = size; @@ -652,7 +688,7 @@ static int uvc_init_video_isoc(struct uvc_video_device *video, * given by the endpoint. */ static int uvc_init_video_bulk(struct uvc_video_device *video, - struct usb_host_endpoint *ep) + struct usb_host_endpoint *ep, gfp_t gfp_flags) { struct urb *urb; unsigned int pipe, i; @@ -671,20 +707,15 @@ static int uvc_init_video_bulk(struct uvc_video_device *video, if (size > psize * UVC_MAX_ISO_PACKETS) size = psize * UVC_MAX_ISO_PACKETS; + if (uvc_alloc_urb_buffers(video, size) < 0) + return -ENOMEM; + pipe = usb_rcvbulkpipe(video->dev->udev, ep->desc.bEndpointAddress); for (i = 0; i < UVC_URBS; ++i) { - urb = usb_alloc_urb(0, GFP_KERNEL); + urb = usb_alloc_urb(0, gfp_flags); if (urb == NULL) { - uvc_uninit_video(video); - return -ENOMEM; - } - - video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev, - size, GFP_KERNEL, &urb->transfer_dma); - if (video->urb_buffer[i] == NULL) { - usb_free_urb(urb); - uvc_uninit_video(video); + uvc_uninit_video(video, 1); return -ENOMEM; } @@ -692,6 +723,7 @@ static int uvc_init_video_bulk(struct uvc_video_device *video, video->urb_buffer[i], size, uvc_video_complete, video); urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; + urb->transfer_dma = video->urb_dma[i]; video->urb[i] = urb; } @@ -702,7 +734,7 @@ static int uvc_init_video_bulk(struct uvc_video_device *video, /* * Initialize isochronous/bulk URBs and allocate transfer buffers. */ -static int uvc_init_video(struct uvc_video_device *video) +static int uvc_init_video(struct uvc_video_device *video, gfp_t gfp_flags) { struct usb_interface *intf = video->streaming->intf; struct usb_host_interface *alts; @@ -747,7 +779,7 @@ static int uvc_init_video(struct uvc_video_device *video) if ((ret = usb_set_interface(video->dev->udev, intfnum, i)) < 0) return ret; - ret = uvc_init_video_isoc(video, ep); + ret = uvc_init_video_isoc(video, ep, gfp_flags); } else { /* Bulk endpoint, proceed to URB initialization. */ ep = uvc_find_endpoint(&intf->altsetting[0], @@ -755,7 +787,7 @@ static int uvc_init_video(struct uvc_video_device *video) if (ep == NULL) return -EIO; - ret = uvc_init_video_bulk(video, ep); + ret = uvc_init_video_bulk(video, ep, gfp_flags); } if (ret < 0) @@ -763,10 +795,10 @@ static int uvc_init_video(struct uvc_video_device *video) /* Submit the URBs. */ for (i = 0; i < UVC_URBS; ++i) { - if ((ret = usb_submit_urb(video->urb[i], GFP_KERNEL)) < 0) { + if ((ret = usb_submit_urb(video->urb[i], gfp_flags)) < 0) { uvc_printk(KERN_ERR, "Failed to submit URB %u " "(%d).\n", i, ret); - uvc_uninit_video(video); + uvc_uninit_video(video, 1); return ret; } } @@ -791,7 +823,7 @@ int uvc_video_suspend(struct uvc_video_device *video) return 0; video->frozen = 1; - uvc_uninit_video(video); + uvc_uninit_video(video, 0); usb_set_interface(video->dev->udev, video->streaming->intfnum, 0); return 0; } @@ -818,7 +850,7 @@ int uvc_video_resume(struct uvc_video_device *video) if (!uvc_queue_streaming(&video->queue)) return 0; - if ((ret = uvc_init_video(video)) < 0) + if ((ret = uvc_init_video(video, GFP_NOIO)) < 0) uvc_queue_enable(&video->queue, 0); return ret; @@ -920,7 +952,7 @@ int uvc_video_enable(struct uvc_video_device *video, int enable) int ret; if (!enable) { - uvc_uninit_video(video); + uvc_uninit_video(video, 1); usb_set_interface(video->dev->udev, video->streaming->intfnum, 0); uvc_queue_enable(&video->queue, 0); @@ -930,6 +962,6 @@ int uvc_video_enable(struct uvc_video_device *video, int enable) if ((ret = uvc_queue_enable(&video->queue, 1)) < 0) return ret; - return uvc_init_video(video); + return uvc_init_video(video, GFP_KERNEL); } diff --git a/linux/drivers/media/video/uvc/uvcvideo.h b/linux/drivers/media/video/uvc/uvcvideo.h index 605a6ccb1..bafe3406e 100644 --- a/linux/drivers/media/video/uvc/uvcvideo.h +++ b/linux/drivers/media/video/uvc/uvcvideo.h @@ -602,6 +602,8 @@ struct uvc_video_device { struct urb *urb[UVC_URBS]; char *urb_buffer[UVC_URBS]; + dma_addr_t urb_dma[UVC_URBS]; + unsigned int urb_size; __u8 last_fid; }; diff --git a/linux/drivers/media/video/v4l2-common.c b/linux/drivers/media/video/v4l2-common.c index b721aca4e..c8b3da9f6 100644 --- a/linux/drivers/media/video/v4l2-common.c +++ b/linux/drivers/media/video/v4l2-common.c @@ -732,9 +732,6 @@ int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver err = probe(client, NULL); if (err == 0) { i2c_attach_client(client); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - MOD_INC_USE_COUNT; -#endif } else { kfree(client); } diff --git a/linux/drivers/media/video/videobuf-dma-sg.c b/linux/drivers/media/video/videobuf-dma-sg.c index 7d459ed6b..39ae44bda 100644 --- a/linux/drivers/media/video/videobuf-dma-sg.c +++ b/linux/drivers/media/video/videobuf-dma-sg.c @@ -265,11 +265,7 @@ int videobuf_dma_sync(struct videobuf_queue *q, struct videobuf_dmabuf *dma) MAGIC_CHECK(dma->magic, MAGIC_DMABUF); BUG_ON(!dma->sglen); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) - dma_sync_sg(q->dev, dma->sglist, dma->nr_pages, dma->direction); -#else dma_sync_sg_for_cpu(q->dev, dma->sglist, dma->nr_pages, dma->direction); -#endif return 0; } @@ -392,13 +388,8 @@ videobuf_vm_close(struct vm_area_struct *vma) */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) static struct page* -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,1) -videobuf_vm_nopage(struct vm_area_struct *vma, unsigned long vaddr, - int write_access) -#else videobuf_vm_nopage(struct vm_area_struct *vma, unsigned long vaddr, int *type) -#endif { struct page *page; @@ -409,15 +400,9 @@ videobuf_vm_nopage(struct vm_area_struct *vma, unsigned long vaddr, page = alloc_page(GFP_USER | __GFP_DMA32); if (!page) return NOPAGE_OOM; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,20) - clear_user_page(page_address(page), vaddr); -#else clear_user_page(page_address(page), vaddr, page); -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,1) if (type) *type = VM_FAULT_MINOR; -#endif return page; } #else diff --git a/linux/drivers/media/video/videobuf-dvb.c b/linux/drivers/media/video/videobuf-dvb.c index 9a821371a..d9979ab26 100644 --- a/linux/drivers/media/video/videobuf-dvb.c +++ b/linux/drivers/media/video/videobuf-dvb.c @@ -13,8 +13,6 @@ * (at your option) any later version. */ -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) - #include <linux/module.h> #include <linux/init.h> #include <linux/device.h> @@ -161,17 +159,10 @@ int videobuf_dvb_register(struct videobuf_dvb *dvb, dvb->name, result); goto fail_adapter; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)) dvb->adapter.priv = adapter_priv; /* register frontend */ result = dvb_register_frontend(&dvb->adapter, dvb->frontend); -#else - dvb->adapter->priv = adapter_priv; - - /* register frontend */ - result = dvb_register_frontend(dvb->adapter, dvb->frontend); -#endif if (result < 0) { printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n", dvb->name, result); @@ -197,11 +188,7 @@ int videobuf_dvb_register(struct videobuf_dvb *dvb, dvb->dmxdev.filternum = 256; dvb->dmxdev.demux = &dvb->demux.dmx; dvb->dmxdev.capabilities = 0; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)) result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); -#else - result = dvb_dmxdev_init(&dvb->dmxdev, dvb->adapter); -#endif if (result < 0) { printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n", dvb->name, result); @@ -232,11 +219,7 @@ int videobuf_dvb_register(struct videobuf_dvb *dvb, } /* register network adapter */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)) dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); -#else - dvb_net_init(dvb->adapter, &dvb->net, &dvb->demux.dmx); -#endif return 0; fail_fe_conn: @@ -251,11 +234,7 @@ fail_dmx: dvb_unregister_frontend(dvb->frontend); fail_frontend: dvb_frontend_detach(dvb->frontend); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)) dvb_unregister_adapter(&dvb->adapter); -#else - dvb_unregister_adapter(dvb->adapter); -#endif fail_adapter: return result; } @@ -269,11 +248,7 @@ void videobuf_dvb_unregister(struct videobuf_dvb *dvb) dvb_dmx_release(&dvb->demux); dvb_unregister_frontend(dvb->frontend); dvb_frontend_detach(dvb->frontend); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)) dvb_unregister_adapter(&dvb->adapter); -#else - dvb_unregister_adapter(dvb->adapter); -#endif } EXPORT_SYMBOL(videobuf_dvb_register); @@ -286,5 +261,3 @@ EXPORT_SYMBOL(videobuf_dvb_unregister); * compile-command: "make DVB=1" * End: */ -#endif /* LINUX_VERSION_CODE */ - diff --git a/linux/drivers/media/video/videodev.c b/linux/drivers/media/video/videodev.c index 8c74621db..91fcf1695 100644 --- a/linux/drivers/media/video/videodev.c +++ b/linux/drivers/media/video/videodev.c @@ -379,42 +379,22 @@ EXPORT_SYMBOL(v4l_printk_ioctl); * sysfs stuff */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -static ssize_t show_index(struct class_device *cd, char *buf) -#else static ssize_t show_index(struct device *cd, struct device_attribute *attr, char *buf) -#endif { struct video_device *vfd = container_of(cd, struct video_device, class_dev); return sprintf(buf, "%i\n", vfd->index); } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -static ssize_t show_name(struct class_device *cd, char *buf) -#else static ssize_t show_name(struct device *cd, struct device_attribute *attr, char *buf) -#endif { struct video_device *vfd = container_of(cd, struct video_device, class_dev); return sprintf(buf, "%.*s\n", (int)sizeof(vfd->name), vfd->name); } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) -static ssize_t show_dev(struct class_device *cd, char *buf) -{ - struct video_device *vfd = container_of(cd, struct video_device, - class_dev); - dev_t dev = MKDEV(VIDEO_MAJOR, vfd->minor); - return print_dev_t(buf,dev); -} - -static DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL); - -#endif struct video_device *video_device_alloc(void) { struct video_device *vfd; @@ -430,11 +410,7 @@ void video_device_release(struct video_device *vfd) } EXPORT_SYMBOL(video_device_release); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -static void video_release(struct class_device *cd) -#else static void video_release(struct device *cd) -#endif { struct video_device *vfd = container_of(cd, struct video_device, class_dev); @@ -447,22 +423,16 @@ static void video_release(struct device *cd) vfd->release(vfd); } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13) static struct device_attribute video_device_attrs[] = { __ATTR(name, S_IRUGO, show_name, NULL), __ATTR(index, S_IRUGO, show_index, NULL), __ATTR_NULL }; -#endif static struct class video_class = { .name = VIDEO_NAME, -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) - .release = video_release, -#else .dev_attrs = video_device_attrs, .dev_release = video_release, -#endif }; /* @@ -2229,46 +2199,17 @@ int video_register_device_index(struct video_device *vfd, int type, int nr, /* sysfs class */ memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev)); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) - if (vfd->dev) - vfd->class_dev.dev = vfd->dev; -#else if (vfd->dev) vfd->class_dev.parent = vfd->dev; -#endif vfd->class_dev.class = &video_class; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12) vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor); -#endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) - sprintf(vfd->class_dev.class_id, "%s%d", name_base, i - base); -#else sprintf(vfd->class_dev.bus_id, "%s%d", name_base, i - base); -#endif ret = device_register(&vfd->class_dev); if (ret < 0) { printk(KERN_ERR "%s: device_register failed\n", __func__); goto fail_minor; } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) - ret = class_device_create_file(&vfd->class_dev, &class_device_attr_name); - if (ret < 0) { - printk(KERN_ERR "%s: class_device_create_file 'name' failed\n", - __FUNCTION__); - class_device_unregister(&vfd->class_dev); - goto fail_minor; - } -#endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) - ret = class_device_create_file(&vfd->class_dev, &class_device_attr_dev); - if (ret < 0) { - printk(KERN_ERR "%s: class_device_create_file 'dev' failed\n", - __FUNCTION__); - class_device_unregister(&vfd->class_dev); - goto fail_minor; - } -#endif #if 1 /* keep */ /* needed until all drivers are fixed */ diff --git a/linux/drivers/media/video/vivi.c b/linux/drivers/media/video/vivi.c index 12307d4bd..98ee2225c 100644 --- a/linux/drivers/media/video/vivi.c +++ b/linux/drivers/media/video/vivi.c @@ -40,9 +40,7 @@ #include <linux/interrupt.h> #include <media/videobuf-vmalloc.h> #include <media/v4l2-common.h> -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) #include <linux/kthread.h> -#endif #include <linux/highmem.h> #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) #include <linux/freezer.h> @@ -161,10 +159,6 @@ struct vivi_dmaqueue { /* thread for generating video stream*/ struct task_struct *kthread; wait_queue_head_t wq; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) - struct semaphore *notify; - int rmmod:1; -#endif /* Counters to control fps rate */ int frame; int ini_jiffies; @@ -446,13 +440,8 @@ static void vivi_sleep(struct vivi_fh *fh) (unsigned long)dma_q); add_wait_queue(&dma_q->wq, &wait); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) - if ((q->rmmod || signal_pending(current))) - goto stop_task; -#else if (kthread_should_stop()) goto stop_task; -#endif /* Calculate time to wake up */ timeout = msecs_to_jiffies(frames_to_ms(1)); @@ -471,20 +460,6 @@ static int vivi_thread(void *data) struct vivi_fh *fh = data; struct vivi_dev *dev = fh->dev; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) - daemonize(); - exit_files(current); - reparent_to_init(); - - spin_lock_irq(SIGMASK_LOCK(current)); - sigfillset(¤t->blocked); - spin_unlock_irq(SIGMASK_LOCK(current)); - strcpy(current->comm, "vivi"); - - dma_q->kthread = current; - if (dma_q->notify != NULL) - up(dma_q->notify); -#endif dprintk(dev, 1, "thread started\n"); set_freezable(); @@ -492,20 +467,10 @@ static int vivi_thread(void *data) for (;;) { vivi_sleep(fh); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) - if (dma_q->rmmod || signal_pending(current)) -#else if (kthread_should_stop()) -#endif break; } dprintk(dev, 1, "thread: exit\n"); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) - dma_q->kthread = NULL; - - if (dma_q->notify != NULL) - up(dma_q->notify); -#endif return 0; } @@ -519,28 +484,12 @@ static int vivi_start_thread(struct vivi_fh *fh) dprintk(dev, 1, "%s\n", __func__); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0) dma_q->kthread = kthread_run(vivi_thread, fh, "vivi"); if (IS_ERR(dma_q->kthread)) { printk(KERN_ERR "vivi: kernel_thread() failed\n"); return PTR_ERR(dma_q->kthread); } -#else - DECLARE_MUTEX_LOCKED(sem); - - dma_q->kthread = NULL; - dma_q->notify = &sem; - dma_q->rmmod = 0; - - if (kernel_thread(vivi_thread, fh, 0) < 0) { - printk(KERN_ERR "sdim: kernel_thread() failed\n"); - return -EINVAL; - } - - down(&sem); - dma_q->notify = NULL; -#endif /* Wakes thread */ wake_up_interruptible(&dma_q->wq); @@ -555,19 +504,7 @@ static void vivi_stop_thread(struct vivi_dmaqueue *dma_q) dprintk(dev, 1, "%s\n", __func__); /* shutdown control thread */ if (dma_q->kthread) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) - DECLARE_MUTEX_LOCKED(sem); - - /* shutdown control thread */ - dma_q->notify = &sem; - dma_q->rmmod = 1; - if (waitqueue_active(&dma_q->wq)) - wake_up_interruptible(&dma_q->wq); - down(&sem); - dma_q->notify = NULL; -#else kthread_stop(dma_q->kthread); -#endif dma_q->kthread = NULL; } } @@ -1130,9 +1067,7 @@ static const struct file_operations vivi_fops = { .read = vivi_read, .poll = vivi_poll, .ioctl = video_ioctl2, /* V4L2 ioctl handler */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) .compat_ioctl = v4l_compat_ioctl32, -#endif .mmap = vivi_mmap, .llseek = no_llseek, }; diff --git a/linux/drivers/media/video/vp27smpx.c b/linux/drivers/media/video/vp27smpx.c index 25a69c7f5..6c47c5e5a 100644 --- a/linux/drivers/media/video/vp27smpx.c +++ b/linux/drivers/media/video/vp27smpx.c @@ -31,10 +31,6 @@ #include <media/v4l2-common.h> #include <media/v4l2-chip-ident.h> #include <media/v4l2-i2c-drv.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -#include "i2c-compat.h" -#include <linux/slab.h> -#endif #include "compat.h" MODULE_DESCRIPTION("vp27smpx driver"); @@ -44,10 +40,6 @@ MODULE_LICENSE("GPL"); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) static unsigned short normal_i2c[] = { 0xb6 >> 1, I2C_CLIENT_END }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif - I2C_CLIENT_INSMOD; #endif @@ -183,14 +175,7 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .command = vp27smpx_command, .probe = vp27smpx_probe, .remove = vp27smpx_remove, -#ifndef I2C_CLASS_TV_ANALOG - .legacy_id = I2C_HW_B_CX2341X, -#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) .id_table = vp27smpx_id, #endif }; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -EXPORT_NO_SYMBOLS; -#endif diff --git a/linux/drivers/media/video/wm8739.c b/linux/drivers/media/video/wm8739.c index d448dcf6e..b361d0d42 100644 --- a/linux/drivers/media/video/wm8739.c +++ b/linux/drivers/media/video/wm8739.c @@ -31,10 +31,6 @@ #include <media/v4l2-common.h> #include <media/v4l2-chip-ident.h> #include <media/v4l2-i2c-drv.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -#include "i2c-compat.h" -#include <linux/slab.h> -#endif #include "compat.h" MODULE_DESCRIPTION("wm8739 driver"); @@ -43,21 +39,13 @@ MODULE_LICENSE("GPL"); static int debug; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) module_param(debug, int, 0644); -#else -MODULE_PARM(debug, "i"); -#endif MODULE_PARM_DESC(debug, "Debug level (0-1)"); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) static unsigned short normal_i2c[] = { 0x34 >> 1, 0x36 >> 1, I2C_CLIENT_END }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif - I2C_CLIENT_INSMOD; #endif @@ -345,14 +333,7 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .command = wm8739_command, .probe = wm8739_probe, .remove = wm8739_remove, -#ifndef I2C_CLASS_TV_ANALOG - .legacy_id = I2C_HW_B_CX2341X, -#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) .id_table = wm8739_id, #endif }; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -EXPORT_NO_SYMBOLS; -#endif diff --git a/linux/drivers/media/video/wm8775.c b/linux/drivers/media/video/wm8775.c index 81a08d674..e7a2e0449 100644 --- a/linux/drivers/media/video/wm8775.c +++ b/linux/drivers/media/video/wm8775.c @@ -35,10 +35,6 @@ #include <media/v4l2-common.h> #include <media/v4l2-chip-ident.h> #include <media/v4l2-i2c-drv-legacy.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -#include "i2c-compat.h" -#include <linux/slab.h> -#endif #include "compat.h" MODULE_DESCRIPTION("wm8775 driver"); @@ -47,10 +43,6 @@ MODULE_LICENSE("GPL"); static unsigned short normal_i2c[] = { 0x36 >> 1, I2C_CLIENT_END }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -#endif - I2C_CLIENT_INSMOD; @@ -242,7 +234,3 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .id_table = wm8775_id, #endif }; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -EXPORT_NO_SYMBOLS; -#endif diff --git a/linux/include/media/pwc-ioctl.h b/linux/include/media/pwc-ioctl.h index 6e32ef4e2..0f19779c4 100644 --- a/linux/include/media/pwc-ioctl.h +++ b/linux/include/media/pwc-ioctl.h @@ -55,12 +55,7 @@ #include <linux/types.h> #include <linux/version.h> -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 10) -/* Compatibility for older kernel */ -typedef __u16 __le16; -#endif - - /* Enumeration of image sizes */ +/* Enumeration of image sizes */ #define PSZ_SQCIF 0x00 #define PSZ_QSIF 0x01 #define PSZ_QCIF 0x02 diff --git a/linux/include/media/v4l2-dev.h b/linux/include/media/v4l2-dev.h index d1ca9664e..fb356eb57 100644 --- a/linux/include/media/v4l2-dev.h +++ b/linux/include/media/v4l2-dev.h @@ -14,9 +14,7 @@ #include <linux/poll.h> #include <linux/fs.h> -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) #include <linux/device.h> -#endif #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15) #include <linux/mutex.h> #else @@ -97,15 +95,9 @@ struct video_device struct file_operations *fops; #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) /* sysfs */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13) struct device class_dev; /* v4l device */ -#else - struct class_device class_dev; -#endif struct device *dev; /* device parent */ -#endif /* device info */ char name[32]; @@ -399,15 +391,9 @@ extern int video_usercopy(struct inode *inode, struct file *file, #ifdef CONFIG_VIDEO_V4L1_COMPAT #include <linux/mm.h> -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) static inline int __must_check -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -video_device_create_file(struct video_device *vfd, - struct class_device_attribute *attr) -#else video_device_create_file(struct video_device *vfd, struct device_attribute *attr) -#endif { int ret = device_create_file(&vfd->class_dev, attr); if (ret < 0) @@ -420,7 +406,6 @@ video_device_remove_file(struct video_device *vfd, { device_remove_file(&vfd->class_dev, attr); } -#endif #endif /* CONFIG_VIDEO_V4L1_COMPAT */ diff --git a/linux/include/media/v4l2-i2c-drv-legacy.h b/linux/include/media/v4l2-i2c-drv-legacy.h index e95e2a072..738f87454 100644 --- a/linux/include/media/v4l2-i2c-drv-legacy.h +++ b/linux/include/media/v4l2-i2c-drv-legacy.h @@ -30,11 +30,7 @@ struct v4l2_i2c_driver_data { int (*suspend)(struct i2c_client *client, pm_message_t state); int (*resume)(struct i2c_client *client); int (*legacy_probe)(struct i2c_adapter *adapter); -#ifdef I2C_CLASS_TV_ANALOG int legacy_class; -#else - int legacy_id; -#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) const struct i2c_device_id *id_table; #endif @@ -49,12 +45,7 @@ static struct i2c_client_address_data addr_data; static struct i2c_driver v4l2_i2c_driver_legacy; static char v4l2_i2c_drv_name_legacy[32]; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) static int v4l2_i2c_drv_attach_legacy(struct i2c_adapter *adapter, int address, int kind) -#else -static int v4l2_i2c_drv_attach_legacy(struct i2c_adapter *adapter, int address, - unsigned short flags, int kind) -#endif { return v4l2_i2c_attach(adapter, address, &v4l2_i2c_driver_legacy, v4l2_i2c_drv_name_legacy, v4l2_i2c_data.probe); @@ -67,11 +58,7 @@ static int v4l2_i2c_drv_probe_legacy(struct i2c_adapter *adapter) return i2c_probe(adapter, &addr_data, v4l2_i2c_drv_attach_legacy); return 0; } -#ifdef I2C_CLASS_TV_ANALOG if (adapter->class & v4l2_i2c_data.legacy_class) -#else - if (adapter->id == v4l2_i2c_data.legacy_id) -#endif return i2c_probe(adapter, &addr_data, v4l2_i2c_drv_attach_legacy); return 0; } @@ -87,14 +74,9 @@ static int v4l2_i2c_drv_detach_legacy(struct i2c_client *client) if (err) return err; kfree(client); - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - MOD_DEC_USE_COUNT; -#endif return 0; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,14) #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,20) static int v4l2_i2c_drv_suspend_helper(struct i2c_client *client, pm_message_t state) @@ -130,19 +112,17 @@ static int v4l2_i2c_drv_resume_helper(struct device * dev, u32 level) #endif return v4l2_i2c_data.resume ? v4l2_i2c_data.resume(client) : 0; } -#endif /* ----------------------------------------------------------------------- */ /* i2c implementation */ static struct i2c_driver v4l2_i2c_driver_legacy = { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) && (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)) +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) .owner = THIS_MODULE, #endif #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) .flags = I2C_DF_NOTIFY, #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) .driver = { #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15) .owner = THIS_MODULE, @@ -152,7 +132,6 @@ static struct i2c_driver v4l2_i2c_driver_legacy = { .resume = v4l2_i2c_drv_resume_helper, #endif }, -#endif .attach_adapter = v4l2_i2c_drv_probe_legacy, .detach_client = v4l2_i2c_drv_detach_legacy, #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,20) @@ -184,13 +163,8 @@ static int __init v4l2_i2c_drv_init(void) strlcpy(v4l2_i2c_drv_name_legacy, v4l2_i2c_data.name, sizeof(v4l2_i2c_drv_name_legacy)); strlcat(v4l2_i2c_drv_name_legacy, "'", sizeof(v4l2_i2c_drv_name_legacy)); -#ifdef I2C_CLASS_TV_ANALOG if (v4l2_i2c_data.legacy_class == 0) v4l2_i2c_data.legacy_class = I2C_CLASS_TV_ANALOG; -#else - if (v4l2_i2c_data.legacy_id == 0) - v4l2_i2c_data.legacy_id = I2C_HW_B_BT848; -#endif #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) strlcpy(v4l2_i2c_driver_legacy.name, v4l2_i2c_drv_name_legacy, sizeof(v4l2_i2c_driver_legacy.name)); diff --git a/linux/include/media/v4l2-i2c-drv.h b/linux/include/media/v4l2-i2c-drv.h index 73d713f07..f74c8a64a 100644 --- a/linux/include/media/v4l2-i2c-drv.h +++ b/linux/include/media/v4l2-i2c-drv.h @@ -35,11 +35,7 @@ struct v4l2_i2c_driver_data { int (*suspend)(struct i2c_client *client, pm_message_t state); int (*resume)(struct i2c_client *client); int (*legacy_probe)(struct i2c_adapter *adapter); -#ifdef I2C_CLASS_TV_ANALOG int legacy_class; -#else - int legacy_id; -#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) const struct i2c_device_id *id_table; #endif @@ -83,12 +79,7 @@ static struct i2c_client_address_data addr_data; /* Bus-based I2C API is not present, add legacy code */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) static int v4l2_i2c_drv_attach_legacy(struct i2c_adapter *adapter, int address, int kind) -#else -static int v4l2_i2c_drv_attach_legacy(struct i2c_adapter *adapter, int address, - unsigned short flags, int kind) -#endif { return v4l2_i2c_attach(adapter, address, &v4l2_i2c_driver, v4l2_i2c_data.name, v4l2_i2c_data.probe); @@ -101,11 +92,7 @@ static int v4l2_i2c_drv_probe_legacy(struct i2c_adapter *adapter) return i2c_probe(adapter, &addr_data, v4l2_i2c_drv_attach_legacy); return 0; } -#ifdef I2C_CLASS_TV_ANALOG if (adapter->class & v4l2_i2c_data.legacy_class) -#else - if (adapter->id == v4l2_i2c_data.legacy_id) -#endif return i2c_probe(adapter, &addr_data, v4l2_i2c_drv_attach_legacy); return 0; } @@ -121,14 +108,9 @@ static int v4l2_i2c_drv_detach_legacy(struct i2c_client *client) if (err) return err; kfree(client); - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - MOD_DEC_USE_COUNT; -#endif return 0; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,14) #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,20) static int v4l2_i2c_drv_suspend_helper(struct i2c_client *client, pm_message_t state) @@ -164,18 +146,16 @@ static int v4l2_i2c_drv_resume_helper(struct device * dev, u32 level) #endif return v4l2_i2c_data.resume ? v4l2_i2c_data.resume(client) : 0; } -#endif /* ----------------------------------------------------------------------- */ static struct i2c_driver v4l2_i2c_driver = { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) && (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)) +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) .owner = THIS_MODULE, #endif #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) .flags = I2C_DF_NOTIFY, #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) .driver = { #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15) .owner = THIS_MODULE, @@ -185,7 +165,6 @@ static struct i2c_driver v4l2_i2c_driver = { .resume = v4l2_i2c_drv_resume_helper, #endif }, -#endif .attach_adapter = v4l2_i2c_drv_probe_legacy, .detach_client = v4l2_i2c_drv_detach_legacy, #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,20) @@ -198,13 +177,8 @@ static struct i2c_driver v4l2_i2c_driver = { static int __init v4l2_i2c_drv_init(void) { -#ifdef I2C_CLASS_TV_ANALOG if (v4l2_i2c_data.legacy_class == 0) v4l2_i2c_data.legacy_class = I2C_CLASS_TV_ANALOG; -#else - if (v4l2_i2c_data.legacy_id == 0) - v4l2_i2c_data.legacy_id = I2C_HW_B_BT848; -#endif #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) strlcpy(v4l2_i2c_driver.name, v4l2_i2c_data.name, sizeof(v4l2_i2c_driver.name)); diff --git a/linux/include/media/videobuf-dvb.h b/linux/include/media/videobuf-dvb.h index 14438bc98..84886be5e 100644 --- a/linux/include/media/videobuf-dvb.h +++ b/linux/include/media/videobuf-dvb.h @@ -20,11 +20,7 @@ struct videobuf_dvb { int nfeeds; /* videobuf_dvb_(un)register manges this */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)) struct dvb_adapter adapter; -#else - struct dvb_adapter *adapter; -#endif struct dvb_demux demux; struct dmxdev dmxdev; struct dmx_frontend fe_hw; diff --git a/linux/sound/pci/bt87x.c b/linux/sound/pci/bt87x.c index 7e6f22041..f9775c090 100644 --- a/linux/sound/pci/bt87x.c +++ b/linux/sound/pci/bt87x.c @@ -37,10 +37,6 @@ #include <sound/control.h> #include <sound/initval.h> #include "compat.h" -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) -/* From linux/pch_ids.h, appeared in 2.6.14 */ -#define PCI_DEVICE_ID_BROOKTREE_879 0x0879 -#endif #ifdef COMPAT_SND_CTL_BOOLEAN_MONO static int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) diff --git a/v4l/compat.h b/v4l/compat.h index 88afe3d83..b59d0ed04 100644 --- a/v4l/compat.h +++ b/v4l/compat.h @@ -31,248 +31,14 @@ #define cancel_delayed_work_sync cancel_rearming_delayed_work #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) -# define minor(x) MINOR(x) -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -# define DEVICE_ATTR(a,b,c,d) CLASS_DEVICE_ATTR(a,b,c,d) -# define device_create_file(a,b) class_device_create_file(a,b) -# define device_remove_file(a,b) class_device_remove_file(a,b) -# define device_register(a) class_device_register(a) -# define device_unregister(a) class_device_unregister(a) -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -# include <linux/moduleparam.h> -# include <linux/delay.h> -# define need_resched() (current->need_resched) -# define work_struct tq_struct -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19) -# define BUG_ON(condition) do { if ((condition)!=0) BUG(); } while(0) -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,23) -# define irqreturn_t void -# define IRQ_RETVAL(foobar) -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,71) -# define strlcpy(dest,src,len) strncpy(dest,src,(len)-1) -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -# define iminor(inode) minor(inode->i_rdev) -#endif - -#if defined(I2C_ADAP_CLASS_TV_ANALOG) && !defined(I2C_CLASS_TV_ANALOG) -# define I2C_CLASS_TV_ANALOG I2C_ADAP_CLASS_TV_ANALOG -# define I2C_CLASS_TV_DIGITAL I2C_ADAP_CLASS_TV_DIGITAL -#endif - #ifndef __pure # define __pure __attribute__((pure)) #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9) -# define __user -# define __kernel -# define __iomem -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) -# define pm_message_t u32 -# define pci_choose_state(pci_dev, state) (state) -# define PCI_D0 (0) -# define assert_spin_locked(foobar) -#endif - -/* Since v4l-dvb now includes it's own copy of linux/i2c-id.h these - are no longer necessary */ -/* -#if !defined(I2C_ALGO_SAA7134) -#define I2C_ALGO_SAA7134 I2C_HW_B_BT848 -#endif -#if !defined(I2C_HW_B_CX2388x) -# define I2C_HW_B_CX2388x I2C_HW_B_BT848 -#endif -#if !defined(I2C_HW_SAA7134) -# define I2C_HW_SAA7134 I2C_ALGO_SAA7134 -#endif -#if !defined(I2C_HW_SAA7146) -# define I2C_HW_SAA7146 I2C_ALGO_SAA7146 -#endif -#if !defined(I2C_HW_B_EM2820) -#define I2C_HW_B_EM2820 0x99 -#endif -*/ - #ifndef I2C_M_IGNORE_NAK # define I2C_M_IGNORE_NAK 0x1000 #endif -/* v4l-dvb uses an out of kernel copy of i2c-id.h, which does not have - some stuff that previous versions of i2c-id.h defined. */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) && defined(LINUX_I2C_ID_H) -# define I2C_ALGO_BIT 0x010000 -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9) -#define __le32 __u32 -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7)) -static inline unsigned long msecs_to_jiffies(const unsigned int m) -{ -#if HZ <= 1000 && !(1000 % HZ) - return (m + (1000 / HZ) - 1) / (1000 / HZ); -#else -#if HZ > 1000 && !(HZ % 1000) - return m * (HZ / 1000); -#else - return (m * HZ + 999) / 1000; -#endif -#endif -} -static inline unsigned int jiffies_to_msecs(const unsigned long j) -{ -#if HZ <= 1000 && !(1000 % HZ) - return (1000 / HZ) * j; -#else -#if HZ > 1000 && !(HZ % 1000) - return (j + (HZ / 1000) - 1)/(HZ / 1000); -#else - return (j * 1000) / HZ; -#endif -#endif -} -static inline void msleep(unsigned int msecs) -{ - unsigned long timeout = msecs_to_jiffies(msecs); - while (timeout) { - set_current_state(TASK_UNINTERRUPTIBLE); - timeout = schedule_timeout(timeout); - } -} -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9) -static inline unsigned long msleep_interruptible(unsigned int msecs) -{ - unsigned long timeout = msecs_to_jiffies(msecs); - - while (timeout) { - set_current_state(TASK_INTERRUPTIBLE); - timeout = schedule_timeout(timeout); - } - return jiffies_to_msecs(timeout); -} -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -/* some keys from 2.6.x which are not (yet?) in 2.4.x */ -# define KEY_PLAY 207 -# define KEY_PRINT 210 -# define KEY_EMAIL 215 -# define KEY_SEARCH 217 -# define KEY_SELECT 0x161 -# define KEY_GOTO 0x162 -# define KEY_INFO 0x166 -# define KEY_CHANNEL 0x16b -# define KEY_LANGUAGE 0x170 -# define KEY_SUBTITLE 0x172 -# define KEY_ZOOM 0x174 -# define KEY_MODE 0x175 -# define KEY_TV 0x179 -# define KEY_CD 0x17f -# define KEY_TUNER 0x182 -# define KEY_TEXT 0x184 -# define KEY_DVD 0x185 -# define KEY_AUDIO 0x188 -# define KEY_VIDEO 0x189 -# define KEY_RED 0x18e -# define KEY_GREEN 0x18f -# define KEY_YELLOW 0x190 -# define KEY_BLUE 0x191 -# define KEY_CHANNELUP 0x192 -# define KEY_CHANNELDOWN 0x193 -# define KEY_RESTART 0x198 -# define KEY_SHUFFLE 0x19a -# define KEY_NEXT 0x197 -# define KEY_RADIO 0x181 -# define KEY_PREVIOUS 0x19c -# define KEY_MHP 0x16f -# define KEY_EPG 0x16d -# define KEY_FASTFORWARD 208 -# define KEY_LIST 0x18b -# define KEY_LAST 0x195 -# define KEY_CLEAR 0x163 -# define KEY_AUX 0x186 -# define KEY_SCREEN 0x177 -# define KEY_PC 0x178 -# define KEY_MEDIA 226 -# define KEY_SLOW 0x199 -# define KEY_OK 0x160 -# define KEY_DIGITS 0x19d -#endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) -# define KEY_SEND 231 -# define KEY_REPLY 232 -# define KEY_FORWARDMAIL 233 -# define KEY_SAVE 234 -# define KEY_DOCUMENTS 235 -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) -#include <linux/mm.h> -static inline unsigned long vmalloc_to_pfn(void * vmalloc_addr) -{ - return page_to_pfn(vmalloc_to_page(vmalloc_addr)); -} - -static unsigned long kvirt_to_pa(unsigned long adr) -{ - unsigned long kva, ret; - - kva = (unsigned long) page_address(vmalloc_to_page((void *)adr)); - kva |= adr & (PAGE_SIZE-1); /* restore the offset */ - ret = __pa(kva); - return ret; -} - -#ifndef wait_event_timeout -#define wait_event_timeout(wq, condition, timeout) \ -({ \ - long __ret = timeout; \ - if (!(condition)) \ - do { \ - DEFINE_WAIT(__wait); \ - for (;;) { \ - prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE); \ - if (condition) \ - break; \ - __ret = schedule_timeout(__ret); \ - if (!__ret) \ - break; \ - } \ - finish_wait(&wq, &__wait); \ - } while (0); \ - __ret; \ -}) -#endif - -#define remap_pfn_range remap_page_range - -#endif - /* vm_insert_page() was added in 2.6.15 */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) && defined(_LINUX_MM_H) static inline int vm_insert_page(struct vm_area_struct *vma, @@ -283,51 +49,7 @@ static inline int vm_insert_page(struct vm_area_struct *vma, } #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9) -#ifndef kcalloc -#define kcalloc(n,size,flags) \ -({ \ - void * __ret = NULL; \ - __ret = kmalloc(n * size, flags); \ - if (__ret) \ - memset(__ret, 0, n * size); \ - __ret; \ -}) -#endif -#endif - -/* try_to_freeze() lost its argument. Must appear after linux/sched.h */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) && defined(_LINUX_SCHED_H) -# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) -# define try_to_freeze() try_to_freeze(PF_FREEZE) -# else -# define try_to_freeze() (0) -# endif -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) -#ifndef kzalloc -#define kzalloc(size, flags) \ -({ \ - void *__ret = kmalloc(size, flags); \ - if (__ret) \ - memset(__ret, 0, size); \ - __ret; \ -}) -#endif -#endif - -/* The class_device system didn't appear until 2.5.69 */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -#define class_device_create_file(a, b) (0) -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -# define class_device_create(a, b, c, d, e, f, g, h) class_simple_device_add(a, c, d, e, f, g, h) -# define class_device_destroy(a, b) class_simple_device_remove(b) -# define class_create(a, b) class_simple_create(a, b) -# define class_destroy(a) class_simple_destroy(a) -#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) # define class_device_create(a, b, c, d, e, f, g, h) class_device_create(a, c, d, e, f, g, h) #endif /* device_create/destroy added in 2.6.18 */ @@ -355,15 +77,6 @@ static inline int vm_insert_page(struct vm_area_struct *vma, #define mutex_trylock(a) down_trylock(a) #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) && defined(_LINUX_SCHED_H) -static inline signed long __sched -schedule_timeout_interruptible(signed long timeout) -{ - __set_current_state(TASK_INTERRUPTIBLE); - return schedule_timeout(timeout); -} -#endif - /* New 4GB DMA zone was added in 2.6.15-rc2 */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) # define __GFP_DMA32 __GFP_DMA @@ -387,25 +100,6 @@ static inline void setup_timer(struct timer_list * timer, #define IRQF_DISABLED SA_INTERRUPT #endif -/* linux/usb.h must be included _before_ compat.h for this code to get - turned on. We can not just include usb.h here, because there is a - lot of code which will not compile if it has usb.h included, due to - conflicts with symbol names. */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) && \ - defined(__LINUX_USB_H) && defined(_INPUT_H) -#include <linux/input.h> -/* Found in linux/usb_input.h in 2.6.13 */ -/* Moved to linux/usb/input.h in 2.6.18 */ -static inline void -usb_to_input_id(const struct usb_device *dev, struct input_id *id) -{ - id->bustype = BUS_USB; - id->vendor = le16_to_cpu(dev->descriptor.idVendor); - id->product = le16_to_cpu(dev->descriptor.idProduct); - id->version = le16_to_cpu(dev->descriptor.bcdDevice); -} -#endif - #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) # define PCIAGP_FAIL 0 @@ -433,11 +127,6 @@ typedef int bool; #define SONY_PIC_COMMAND_SETCAMERA SONYPI_COMMAND_SETCAMERA #endif -/* Parameter to pci_match_device() changed in 2.6.13-rc2 */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) && defined(LINUX_PCI_H) -#define pci_match_device(drv, dev) pci_match_device((drv)->id_table, dev) -#endif - /* pci_dev got a new revision field in 2.6.23-rc1 */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) && defined(LINUX_PCI_H) /* Just make it easier to subsitute pci_dev->revision with diff --git a/v4l/scripts/release.sh b/v4l/scripts/release.sh index 557172875..4e9c810bc 100755 --- a/v4l/scripts/release.sh +++ b/v4l/scripts/release.sh @@ -9,7 +9,7 @@ ver_cx="0.0.4" # common files files_v4l="v4l*.[ch] video-buf.[ch] videodev*.h" files_tuner="tuner.[ch] tda9887.[ch]" -files_i2c="id.h audiochip.h i2c-compat.h" +files_i2c="id.h audiochip.h" files_common="$files_v4l $files_tuner $files_i2c doc" # other files diff --git a/v4l/scripts/strip-trailing-whitespaces.sh b/v4l/scripts/strip-trailing-whitespaces.sh index 9bd963025..cb341ce76 100755 --- a/v4l/scripts/strip-trailing-whitespaces.sh +++ b/v4l/scripts/strip-trailing-whitespaces.sh @@ -20,6 +20,12 @@ else fi for file in `eval $files`; do + case "$file" in + *.patch) + continue + ;; + esac + perl -ne ' s/[ \t]+$//; s<^ {8}> <\t>; diff --git a/v4l2-apps/lib/libv4l/ChangeLog b/v4l2-apps/lib/libv4l/ChangeLog new file mode 100644 index 000000000..14c5625a1 --- /dev/null +++ b/v4l2-apps/lib/libv4l/ChangeLog @@ -0,0 +1,165 @@ +libv4l-0.3.4 +------------ +* The mmap64 support in 0.3.3, has caused a bug in libv4l1 when running on + 32 bit systems (who uses those now a days?), this bug caused v4l1 + compatibility to not work at all, this release fixes this +* Some apps (xawtv, kopete) use an ioctl wrapper internally for various + reasons. This wrappers request argument is an int, but the real ioctl's + request argument is an unsigned long. Passing the VIDIOC_xxx defines through + to the wrapper, and then to the real ioctl, causes the request to get sign + extended on 64 bit args. The kernel seems to ignore the upper 32 bits, + causing the sign extension to not make a difference. libv4l now also + ignores the upper 32 bits of the libv4lx_ioctl request argument on 64 bit + archs +* Add a bugfix patch for kopete in the appl-patches dir, currently it assumes + that it got the width and height it asked for when doing a S_FMT, which is a + wrong assumption + + +libv4l-0.3.3 +------------ +* Add open64 and mmap64 wrappers to the LD_PRELOAD wrapper libs, so that + they also work for applications compiled with FILE_OFFSET_BITS=64, this + fixes using them with v4l-info +* While looking at xawtv in general, found a few bugs in xawtv itself, added + a patch to fix those to the appl-patches dir +* Talking about the appl-patches dir, restore that as it accidentally got + dropped from 0.3.2 +* Be more verbose in various places when it comes to logging (esp errors) +* Change v4lconvert_enum_fmt code a bit, so that it is easier to add more + supported destination formats to libv4lconvert +* Don't return -EINVAL from try_fmt when we cannot convert because the cam + doesn't have any formats we know. Instead just return as format whatever the + cam returns from try_fmt, this new behavior is compliant with the v4l2 + api as documented + +libv4l-0.3.2 +------------ +* Add support for converting from sn9c10x compressed data +* Add support for converting from pac207 compressed data +* Add "make install" Makefile target + +libv4l-0.3.1 +------------ +* Only serialize V4L2_BUF_TYPE_VIDEO_CAPTURE type ioctls +* Do not return an uninitialized variable as result code for GPICT + (fixes vlc, but see below) +* Add an apps-patches directory which includes: + * vlc-0.8.6-libv4l1.patch, modify vlc's v4l1 plugin to directly call into + libv4l1, in the end we want all apps todo this as its better then + LD_PRELOAD tricks, but for vlc this is needed as vlc's plugin system + causes LD_PRELOAD to not work on symbols in the plugins + * camorama-0.19-fixes.patch, small bugfixes to camorama's v4l1 support, + this patch only fixes _real_ bugs in camorama and does not change it to + work with v4l1compat. Although it does work better with these bugs fixed + :) With this patch and LD_PRELOAD=<path>/v4l1compat.so it works + flawless. + + +libv4l-0.3 +---------- +* add extern "C" magic to public header files for c++ usage (Gregor Jasny) +* Make libv4l1 and libv4l2 multithread use safe, see README.multi-threading +* Add v4lx_dup() calls (and intercept dup() from the wrappers) this fixes + use with gstreamer's v4l2 plugin (tested with cheese) +* Hopefully definitely fix compile errors on systems with a broken videodev2.h + +libv4l-0.2 +---------- +*** API change *** +* Change v4lconvert api so that the v4lconvert struct always gets allocated + by the library, this to make it opaque, so that we can avoid future API + and ABI changes +* Add support for yuv420 -> bgr24 conversion +* When converting from v4l2 pixelformat to v4l12 palette return + VIDEO_PALETTE_YUV420P instead of VIDEO_PALETTE_YUV420 for + V4L2_PIX_FMT_YUV420 as that is what most apps seem to expect +* override kernel v4l1 compat min / max size with our own more accurate values +* fix v4l1 munmap bug where it didn't recognise the buffer being unmapped was + our fake buffer (fixes gstreamer v4l1 support, checked with cheese) +* add support for reporting the emulated pixelformats with ENUM_FMT, this + defaults to off, and can be activated by passing a flag to enable it to + v4l2_fd_open. This gets enabled by default the wrappers. +* v4l2: mmap the real device buffers before doing conversion when DQBUF gets + called before the application has called mmap (avoid crash). + + +libv4l-0.1 +---------- +* major shuffle / rewrite now split into libv4l1, libv4l2, libv4lconvert + and 2 wrappers for binary compatibility +* rewritten LGPL bayer decoding +* many many other changes and fixes + + +v4l1-compat-0.6 (V4L2 apps stay working) +---------------------------------------- +* Do not go into emulation mode of rgb24 immediately, but only after a + GPICT ioctl which has not been preceded by a SPICT ioctl, AKA do not get + in the way of V4L2 read calls by doing conversion on them +* Do not get in the way of mmap calls made by V4L2 applications +* Fix swapping of red and blue in bayer -> bgr24 decode routine +* Remember the v4l1 palette asked for with SPICT and return that, as + otherwise we loose information when going v4l1 -> v4l2 -> v4l1, for example + YUV420P becomes YUV420, which are separate in v4l1. + + +v4l1-compat-0.5 (perfect camorama) +---------------------------------- +* Allow changing of format after the buffers have been mapped, by tearing + down the entire house, changing the fundament and then rebuilding it. + Now changing the capture resolution in camorama works! +* Fix jpeg decoding error reporting +* Allow jpeg's with a height which is a multiple of 8 (was 16) +* Remove a number of pretty new VIDIOCXXX -> string mappings from log.c, + fixing compiling with somewhat older kernels + + +v4l1-compat 0.4 +--------------- +* Do not even try to change the format in v4l1_compat_set_format(), unless + _really_ necessary. +* Cleanup ambigious use of src_format (no functional changes) +* Drop the mmap hack for zerocopy access under certain conditions, one of them + that the cam can deliver the requested format. Although avoiding the + memcpy in this scenarios is a good thing todo, there were several issues + with the 0.3 implementation of this, fixing all these means adding lots of + special cases all over the code. So instead we just drop support and + always do atleast a memcpy (or a conversion). If an application cannot + live with the speed penalty this imposes it should be ported to v4l2. +* Now that we've gotten rid of the zerocopy mmap hack, we can safely allow + mixing read and mmap based IO. +* Explictly include linux/ioctl.h, to fix compile with kernel headers where + linux/videodev.h doesn't. + + +v4l1-compat 0.3 +--------------- +* Don't allow multiple opens, in theory our code can handle it, but not all + v4l2 devices like it (ekiga does it and uvc doesn't like it). + + +v4l1-compat 0.2 +--------------- +* When mmap gets passed an fd of -1 (anonymous map) don't look for it in our + list of managed fds, as we use -1 to mark unused entries (fixes ekiga + crashing). Also check for an fd of -1 in the other calls we intercept. +* In close() start with removing the fd from our list of managed fds, this must + be done first, because as soon as we've done the actual close syscall, the + fd maybe returned by an open in another thread and we don't want to intercept + calls to this new fd. +* Make unknown v4l1 palette types a normal level log messages instead of an + error. +* When an applicaiton changes the width / height through the CMCAPTURE ioctl + remember the new width and height. +* If the devices initial v4l2 pixformat has no corresponding v4l1 palette, try + setting a format which does (and which we emulate when necessary) so that + applicactions which just query the current format (GPICT) and then take + whatever they get will work (partially fixes camorama) +* Implement our own SWIN instead of using kernel compat layer, for more + flexibility and better error checking + + +v4l1-compat 0.1 +--------------- +* Initial public release. diff --git a/v4l2-apps/lib/libv4l/Makefile b/v4l2-apps/lib/libv4l/Makefile new file mode 100644 index 000000000..d9654f163 --- /dev/null +++ b/v4l2-apps/lib/libv4l/Makefile @@ -0,0 +1,16 @@ +LIB_RELEASE=0 +V4L2_LIB_VERSION=$(LIB_RELEASE).3.2 + +all clean install: + $(MAKE) -C libv4lconvert $@ + $(MAKE) -C libv4l2 $@ + $(MAKE) -C libv4l1 $@ + +export: clean + mkdir /tmp/libv4l-$(V4L2_LIB_VERSION) + cp -a . /tmp/libv4l-$(V4L2_LIB_VERSION)/ + cd /tmp/ && \ + tar cvf /tmp/libv4l-$(V4L2_LIB_VERSION).tar\ + libv4l-$(V4L2_LIB_VERSION) + gzip /tmp/libv4l-$(V4L2_LIB_VERSION).tar + rm -rf /tmp/libv4l-$(V4L2_LIB_VERSION) diff --git a/v4l2-apps/lib/libv4l/README b/v4l2-apps/lib/libv4l/README new file mode 100644 index 000000000..b9b056f66 --- /dev/null +++ b/v4l2-apps/lib/libv4l/README @@ -0,0 +1,141 @@ +Introduction +------------ + +libv4l is a collection of libraries which adds a thin abstraction layer on +top of video4linux2 devices. The purpose of this (thin) layer is to make it +easy for application writers to support a wide variety of devices without +having to write seperate code for different devices in the same class. + +All libv4l components are licensed under the GNU Library General Publishing +License version 2 or (at your option) any later version. + +libv4l consists of 3 different libraries: + + +libv4lconvert +------------- + +libv4lconvert offers functions to convert from any (known) pixelformat +to V4l2_PIX_FMT_BGR24 or V4l2_PIX_FMT_YUV420. + +Currently the following source formats are supported: +jpeg, mjpeg, bayer (all 4 variants: bggr, rggb, gbrg, grbg), +spca501 (chip specific yuv 420 with interlaced components), +spca561 (chip specific compressed gbrg bayer) +For more details on the v4lconvert_ functions see libv4lconvert.h . + + +libv4l1 +------- + +This offers functions like v4l1_open, v4l1_ioctl, etc. which can by used to +quickly make v4l1 applications work with v4l2 devices. These functions work +exactly like the normal open/close/etc, except that libv4l1 does full emulation +of the v4l1 api on top of v4l2 drivers, in case of v4l1 drivers it will just +pass calls through. For more details on the v4l1_ functions see libv4l1.h . + + +libv4l2 +------- + +This offers functions like v4l2_open, v4l2_ioctl, etc. which can by used to +quickly make v4l2 applications work with v4l2 devices with weird formats. +libv4l2 mostly passes calls directly through to the v4l2 driver. When the +app does a TRY_FMT / S_FMT with a not supported format libv4l2 will get in +the middle and emulate the format (if an app wants to know which formats the +hardware can _really_ do it should use ENUM_FMT, not randomly try a bunch of +S_FMT's). For more details on the v4l2_ functions see libv4l2.h . + + +wrappers +-------- + +The functionality provided by libv4l1 for v4l1 apps and libv4l2 for v4l2 apps +can also be used by existing apps without modifying them. For this purpose +2 wrapper libraries are provided which can be preloaded before starting the +application using the LD_PRELOAD environment variable. These wrappers will +then intercept calls to open/close/ioctl/etc. and if these calls directed +towards a video device the wrapper will redirect the call to the libv4lX +counterparts. + +The preloadable libv4l1 wrapper which adds v4l2 device compatibility to v4l1 +applications is called v4l1compat.so. The preloadable libv4l2 wrapper which +adds support for various pixelformats to v4l2 applications is called +v4l2convert.so. + +Example usage (after install in default location): +$ export LD_PRELOAD=/usr/local/lib/libv4l/v4l1compat.so +$ camorama + + +Installation Instructions +------------------------- + +Simple type the following commands from the libv4l-x.y.z directory +(adjusting PREFIX as desired): +make +make install PREFIX=/usr/local + +Note: make install also supports the DESTDIR=... paramter for installation +into chroots. + + +FAQ +--- + +Q: Why libv4l, whats wrong with directly accessing v4l2 devices ? +Q: Do we really need yet another library ? +A: Current webcam using applications like ekiga contain code to handle many +different specific pixelformats webcam's use, but that code only supports a +small subset of all native webcam (compressed) pixelformats. Other current +v4l2 applications do not support anything but rgb pixelformats (xawtv for +example) and this will not work with most webcams at all. + +With gspca being ported to v4l2 and thus decoding to normal formats being +removed from the device driver as this really belongs in userspace, ekiga +would need to be extended with many more often chip dependent formats, like +the bayer compression used by the spca561 and the (different) compression used +by the pac207 and the (again different) compression used by the sn9c102. Adding +support for all these formats should not be done at the application level, as +then it needs to be written for each application seperately. Licensing issues +with the decompressors will then also become a problem as just cut and pasting +from one application to another is bound to hit license incompatibilities. + +So clearly this belongs in a library, and in a library with a license which +allows this code to be used from as many different applications as possible. +Hence libv4l was born. + +Q: Under which license may I use and distribute libv4l? +A: All libv4l components are licensed under the GNU Library General Publishing +License version 2 or (at your option) any later version. See the included +COPYING.LIB file. + +Q: Okay so I get the use of having a libv4lconvert, but why libv4l1 ? +A: Many v4l2 drivers do not offer full v4l1 compatibility. They often do not +implemented the CGMBUF ioctl and v4l1 style mmap call. Adding support to all +these drivers for this is a lot of work and more importantly unnecessary +adds code to kernel space. + +Also even if the CGMBUF ioctl and v4l1 style mmap are supported, then most +cams still deliver pixelformats which v4l1 applications do not understand. + +This libv4l1 was born as an easy way to get v4l1 applications to work with +v4l2 devices without requiring full v4l1 emulation (including format +conversion) in the kernel, and without requiring major changes to the +applications. + + +Q: Why should I use libv4l2 in my app instead of direct device access +combined with libv4lconvert? + +libv4l2 is mainly meant for quickly and easily adding support for more +pixelformats to existing v4l2 applications. So if you feel better directly +accessing the device in combination with libv4lconvert thats fine too. + +Notice that libv4l2 also does emulation of the read() call on devices which +do not support it in the driver. In the background this uses mmap buffers +(even on devices which do support the read call). This mmap gives libv4lconvert +zero-copy access to the captured frame, and then it can write the converted +data directly to the buffer the application provided to v4l2_read(). Thus +another reason to use liv4l2 is to get the no memcpy advantage of the mmap +capture method combined with the simplicity of making a simple read() call. diff --git a/v4l2-apps/lib/libv4l/README.multi-threading b/v4l2-apps/lib/libv4l/README.multi-threading new file mode 100644 index 000000000..93b393c8c --- /dev/null +++ b/v4l2-apps/lib/libv4l/README.multi-threading @@ -0,0 +1,12 @@ +libv4lconvert is not safe for using one convert instance as returned by +v4lconvert_create from multiple threads, if you want to use one v4lconvert +instance from multiple threads you must provide your own locking and make +sure no simultanious calls are made. + +libv4l1 and libv4l2 are safe for multithread use *under* *the* *following* +*conditions* : + +* when using v4lx_fd_open, do not make any v4lx_ calls to the passed fd until + v4lx_fd_open has completed + +* all v4lx_ calls must be completed before calling v4lx_close diff --git a/v4l2-apps/lib/libv4l/TODO b/v4l2-apps/lib/libv4l/TODO new file mode 100644 index 000000000..f3f9ff527 --- /dev/null +++ b/v4l2-apps/lib/libv4l/TODO @@ -0,0 +1,12 @@ +-add support for setting / getting the number of read buffers + +-add code to v4l2_read to not return frames more then say 5 seconds old + +-add support for libv4l1 for non pure capture (combined capture and overlay) + devices so that atleast CGMBUF emulation (but no conversion, as thats + impossible for overlays) can be done, so that it will no longer be + necessary to implement CGMBUF in the kernel for each driver. + +-check v4l2_field during conversion + +-add conversion from bgr24 to yuv420 diff --git a/v4l2-apps/lib/libv4l/appl-patches/camorama-0.19-fixes.patch b/v4l2-apps/lib/libv4l/appl-patches/camorama-0.19-fixes.patch new file mode 100644 index 000000000..1e1333575 --- /dev/null +++ b/v4l2-apps/lib/libv4l/appl-patches/camorama-0.19-fixes.patch @@ -0,0 +1,90 @@ +--- camorama-0.19/src/callbacks.c 2007-09-16 15:36:55.000000000 +0200 ++++ camorama-0.19.new/src/callbacks.c 2008-06-29 22:22:44.000000000 +0200 +@@ -387,9 +387,6 @@ + } + } + +- cam->pixmap = gdk_pixmap_new (NULL, cam->x, cam->y, cam->desk_depth); +- gtk_widget_set_size_request (glade_xml_get_widget (cam->xml, "da"), +- cam->x, cam->y); + + /* + * if(cam->read == FALSE) { +@@ -441,6 +438,11 @@ + * * } + */ + get_win_info (cam); ++ ++ cam->pixmap = gdk_pixmap_new (NULL, cam->x, cam->y, cam->desk_depth); ++ gtk_widget_set_size_request (glade_xml_get_widget (cam->xml, "da"), ++ cam->x, cam->y); ++ + frame = 0; + gtk_window_resize (GTK_WINDOW + (glade_xml_get_widget (cam->xml, "main_window")), 320, +@@ -520,8 +522,14 @@ + gtk_widget_show (about); + } + ++void ++camorama_filter_color_filter(void* filter, guchar *image, int x, int y, int depth); ++ + static void + apply_filters(cam* cam) { ++ /* v4l has reverse rgb order from what camora expect so call the color ++ filter to fix things up before running the user selected filters */ ++ camorama_filter_color_filter(NULL, cam->pic_buf, cam->x, cam->y, cam->depth); + camorama_filter_chain_apply(cam->filter_chain, cam->pic_buf, cam->x, cam->y, cam->depth); + #warning "FIXME: enable the threshold channel filter" + // if((effect_mask & CAMORAMA_FILTER_THRESHOLD_CHANNEL) != 0) +--- camorama-0.19/src/filter.c 2007-09-16 14:48:50.000000000 +0200 ++++ camorama-0.19.new/src/filter.c 2008-06-29 22:11:42.000000000 +0200 +@@ -151,12 +151,12 @@ + static void + camorama_filter_color_init(CamoramaFilterColor* self) {} + +-static void ++void + camorama_filter_color_filter(CamoramaFilterColor* filter, guchar *image, int x, int y, int depth) { + int i; + char tmp; + i = x * y; +- while (--i) { ++ while (i--) { + tmp = image[0]; + image[0] = image[2]; + image[2] = tmp; +--- camorama-0.19/src/main.c 2007-09-16 15:36:55.000000000 +0200 ++++ camorama-0.19.new/src/main.c 2008-06-29 22:20:04.000000000 +0200 +@@ -224,8 +224,7 @@ + + /* get picture attributes */ + get_pic_info (cam); +-// set_pic_info(cam); +- /* set_pic_info(cam); */ ++ set_pic_info (cam); + cam->contrast = cam->vid_pic.contrast; + cam->brightness = cam->vid_pic.brightness; + cam->colour = cam->vid_pic.colour; +--- camorama-0.19/src/v4l.c 2007-09-16 14:48:05.000000000 +0200 ++++ camorama-0.19.new/src/v4l.c 2008-06-29 22:20:23.000000000 +0200 +@@ -158,8 +158,8 @@ + if(cam->debug) { + g_message("SET PIC"); + } +- //cam->vid_pic.palette = VIDEO_PALETTE_RGB24; +- //cam->vid_pic.depth = 24; ++ cam->vid_pic.palette = VIDEO_PALETTE_RGB24; ++ cam->vid_pic.depth = 24; + //cam->vid_pic.palette = VIDEO_PALETTE_YUV420P; + if(ioctl(cam->dev, VIDIOCSPICT, &cam->vid_pic) == -1) { + if(cam->debug) { +@@ -232,6 +232,8 @@ + exit(0); + } + ++ cam->x = cam->vid_win.width; ++ cam->y = cam->vid_win.height; + } + + void set_buffer(cam * cam) diff --git a/v4l2-apps/lib/libv4l/appl-patches/kdenetwork-4.0.85-kopete.patch b/v4l2-apps/lib/libv4l/appl-patches/kdenetwork-4.0.85-kopete.patch new file mode 100644 index 000000000..b187f05e4 --- /dev/null +++ b/v4l2-apps/lib/libv4l/appl-patches/kdenetwork-4.0.85-kopete.patch @@ -0,0 +1,12 @@ +diff -up kdenetwork-4.0.85/kopete/libkopete/avdevice/videodevice.cpp~ kdenetwork-4.0.85/kopete/libkopete/avdevice/videodevice.cpp +--- kdenetwork-4.0.85/kopete/libkopete/avdevice/videodevice.cpp~ 2008-07-07 22:40:56.000000000 +0200 ++++ kdenetwork-4.0.85/kopete/libkopete/avdevice/videodevice.cpp 2008-07-07 22:40:56.000000000 +0200 +@@ -679,6 +679,8 @@ kDebug() << "VIDIOC_S_FMT worked (" << e + if (fmt.fmt.pix.sizeimage < min) + fmt.fmt.pix.sizeimage = min; + m_buffer_size=fmt.fmt.pix.sizeimage ; ++ currentwidth = fmt.fmt.pix.width; ++ currentheight = fmt.fmt.pix.height; + } + break; + #endif diff --git a/v4l2-apps/lib/libv4l/appl-patches/vlc-0.8.6-libv4l1.patch b/v4l2-apps/lib/libv4l/appl-patches/vlc-0.8.6-libv4l1.patch new file mode 100644 index 000000000..132549b55 --- /dev/null +++ b/v4l2-apps/lib/libv4l/appl-patches/vlc-0.8.6-libv4l1.patch @@ -0,0 +1,319 @@ +diff -up vlc-0.8.6f/modules/access/v4l/Makefile.am~ vlc-0.8.6f/modules/access/v4l/Makefile.am +--- vlc-0.8.6f/modules/access/v4l/Makefile.am~ 2008-06-29 17:14:11.000000000 +0200 ++++ vlc-0.8.6f/modules/access/v4l/Makefile.am 2008-06-29 17:16:39.000000000 +0200 +@@ -100,7 +100,7 @@ libv4l_plugin_la_CXXFLAGS = `$(VLC_CONFI + libv4l_plugin_la_OBJCFLAGS = `$(VLC_CONFIG) --objcflags plugin v4l` + libv4l_plugin_la_LDFLAGS = `$(VLC_CONFIG) --libs plugin v4l` \ + -rpath '$(libvlcdir)' -avoid-version -module -shrext $(LIBEXT) +-libv4l_plugin_la_LIBADD = $(LTLIBVLC) ++libv4l_plugin_la_LIBADD = $(LTLIBVLC) -lv4l1 + + libv4l_a_SOURCES = $(SOURCES_v4l) + libv4l_builtin_la_SOURCES = $(SOURCES_v4l) +diff -up vlc-0.8.6f/modules/access/v4l/Makefile.in~ vlc-0.8.6f/modules/access/v4l/Makefile.in +--- vlc-0.8.6f/modules/access/v4l/Makefile.in~ 2008-06-29 17:16:22.000000000 +0200 ++++ vlc-0.8.6f/modules/access/v4l/Makefile.in 2008-06-29 17:16:42.000000000 +0200 +@@ -390,7 +390,7 @@ libv4l_plugin_la_OBJCFLAGS = `$(VLC_CONF + libv4l_plugin_la_LDFLAGS = `$(VLC_CONFIG) --libs plugin v4l` \ + -rpath '$(libvlcdir)' -avoid-version -module -shrext $(LIBEXT) + +-libv4l_plugin_la_LIBADD = $(LTLIBVLC) ++libv4l_plugin_la_LIBADD = $(LTLIBVLC) -lv4l1 + libv4l_a_SOURCES = $(SOURCES_v4l) + libv4l_builtin_la_SOURCES = $(SOURCES_v4l) + libv4l_a_CFLAGS = `$(VLC_CONFIG) --cflags builtin pic v4l` +diff -up vlc-0.8.6f/modules/access/v4l/v4l.c~ vlc-0.8.6f/modules/access/v4l/v4l.c +--- vlc-0.8.6f/modules/access/v4l/v4l.c~ 2008-06-29 17:13:30.000000000 +0200 ++++ vlc-0.8.6f/modules/access/v4l/v4l.c 2008-06-29 17:13:30.000000000 +0200 +@@ -64,6 +64,9 @@ + + #include <sys/soundcard.h> + ++#include <libv4l1.h> ++ ++ + /***************************************************************************** + * Module descriptior + *****************************************************************************/ +@@ -546,23 +549,23 @@ static void Close( vlc_object_t *p_this + if( p_sys->psz_device ) free( p_sys->psz_device ); + if( p_sys->psz_vdev ) free( p_sys->psz_vdev ); + if( p_sys->psz_adev ) free( p_sys->psz_adev ); +- if( p_sys->fd_video >= 0 ) close( p_sys->fd_video ); ++ if( p_sys->fd_video >= 0 ) v4l1_close( p_sys->fd_video ); + if( p_sys->fd_audio >= 0 ) close( p_sys->fd_audio ); + if( p_sys->p_block_audio ) block_Release( p_sys->p_block_audio ); + + if( p_sys->b_mjpeg ) + { + int i_noframe = -1; +- ioctl( p_sys->fd_video, MJPIOC_QBUF_CAPT, &i_noframe ); ++ v4l1_ioctl( p_sys->fd_video, MJPIOC_QBUF_CAPT, &i_noframe ); + } + + if( p_sys->p_video_mmap && p_sys->p_video_mmap != MAP_FAILED ) + { + if( p_sys->b_mjpeg ) +- munmap( p_sys->p_video_mmap, p_sys->mjpeg_buffers.size * ++ v4l1_munmap( p_sys->p_video_mmap, p_sys->mjpeg_buffers.size * + p_sys->mjpeg_buffers.count ); + else +- munmap( p_sys->p_video_mmap, p_sys->vid_mbuf.size ); ++ v4l1_munmap( p_sys->p_video_mmap, p_sys->vid_mbuf.size ); + } + + free( p_sys ); +@@ -875,13 +878,13 @@ static int OpenVideoDev( demux_t *p_demu + struct mjpeg_params mjpeg; + int i; + +- if( ( i_fd = open( psz_device, O_RDWR ) ) < 0 ) ++ if( ( i_fd = v4l1_open( psz_device, O_RDWR ) ) < 0 ) + { + msg_Err( p_demux, "cannot open device (%s)", strerror( errno ) ); + goto vdev_failed; + } + +- if( ioctl( i_fd, VIDIOCGCAP, &p_sys->vid_cap ) < 0 ) ++ if( v4l1_ioctl( i_fd, VIDIOCGCAP, &p_sys->vid_cap ) < 0 ) + { + msg_Err( p_demux, "cannot get capabilities (%s)", strerror( errno ) ); + goto vdev_failed; +@@ -926,7 +929,7 @@ static int OpenVideoDev( demux_t *p_demu + } + + vid_channel.channel = p_sys->i_channel; +- if( ioctl( i_fd, VIDIOCGCHAN, &vid_channel ) < 0 ) ++ if( v4l1_ioctl( i_fd, VIDIOCGCHAN, &vid_channel ) < 0 ) + { + msg_Err( p_demux, "cannot get channel infos (%s)", + strerror( errno ) ); +@@ -944,7 +947,7 @@ static int OpenVideoDev( demux_t *p_demu + } + + vid_channel.norm = p_sys->i_norm; +- if( ioctl( i_fd, VIDIOCSCHAN, &vid_channel ) < 0 ) ++ if( v4l1_ioctl( i_fd, VIDIOCSCHAN, &vid_channel ) < 0 ) + { + msg_Err( p_demux, "cannot set channel (%s)", strerror( errno ) ); + goto vdev_failed; +@@ -959,7 +962,7 @@ static int OpenVideoDev( demux_t *p_demu + if( p_sys->i_tuner >= 0 ) + { + vid_tuner.tuner = p_sys->i_tuner; +- if( ioctl( i_fd, VIDIOCGTUNER, &vid_tuner ) < 0 ) ++ if( v4l1_ioctl( i_fd, VIDIOCGTUNER, &vid_tuner ) < 0 ) + { + msg_Err( p_demux, "cannot get tuner (%s)", strerror( errno ) ); + goto vdev_failed; +@@ -974,7 +977,7 @@ static int OpenVideoDev( demux_t *p_demu + + /* FIXME FIXME to be checked FIXME FIXME */ + //vid_tuner.mode = p_sys->i_norm; +- if( ioctl( i_fd, VIDIOCSTUNER, &vid_tuner ) < 0 ) ++ if( v4l1_ioctl( i_fd, VIDIOCSTUNER, &vid_tuner ) < 0 ) + { + msg_Err( p_demux, "cannot set tuner (%s)", strerror( errno ) ); + goto vdev_failed; +@@ -990,7 +993,7 @@ static int OpenVideoDev( demux_t *p_demu + if( p_sys->i_frequency >= 0 ) + { + int driver_frequency = p_sys->i_frequency * 16 /1000; +- if( ioctl( i_fd, VIDIOCSFREQ, &driver_frequency ) < 0 ) ++ if( v4l1_ioctl( i_fd, VIDIOCSFREQ, &driver_frequency ) < 0 ) + { + msg_Err( p_demux, "cannot set frequency (%s)", + strerror( errno ) ); +@@ -1010,7 +1013,7 @@ static int OpenVideoDev( demux_t *p_demu + if( p_sys->i_audio >= 0 ) + { + vid_audio.audio = p_sys->i_audio; +- if( ioctl( i_fd, VIDIOCGAUDIO, &vid_audio ) < 0 ) ++ if( v4l1_ioctl( i_fd, VIDIOCGAUDIO, &vid_audio ) < 0 ) + { + msg_Err( p_demux, "cannot get audio (%s)", strerror( errno ) ); + goto vdev_failed; +@@ -1019,7 +1022,7 @@ static int OpenVideoDev( demux_t *p_demu + /* unmute audio */ + vid_audio.flags &= ~VIDEO_AUDIO_MUTE; + +- if( ioctl( i_fd, VIDIOCSAUDIO, &vid_audio ) < 0 ) ++ if( v4l1_ioctl( i_fd, VIDIOCSAUDIO, &vid_audio ) < 0 ) + { + msg_Err( p_demux, "cannot set audio (%s)", strerror( errno ) ); + goto vdev_failed; +@@ -1035,7 +1038,7 @@ static int OpenVideoDev( demux_t *p_demu + struct quicktime_mjpeg_app1 *p_app1; + int32_t i_offset; + +- if( ioctl( i_fd, MJPIOC_G_PARAMS, &mjpeg ) < 0 ) ++ if( v4l1_ioctl( i_fd, MJPIOC_G_PARAMS, &mjpeg ) < 0 ) + { + msg_Err( p_demux, "cannot get mjpeg params (%s)", + strerror( errno ) ); +@@ -1086,7 +1089,7 @@ static int OpenVideoDev( demux_t *p_demu + * optional. They will be present in the output. */ + mjpeg.jpeg_markers = JPEG_MARKER_DHT | JPEG_MARKER_DQT; + +- if( ioctl( i_fd, MJPIOC_S_PARAMS, &mjpeg ) < 0 ) ++ if( v4l1_ioctl( i_fd, MJPIOC_S_PARAMS, &mjpeg ) < 0 ) + { + msg_Err( p_demux, "cannot set mjpeg params (%s)", + strerror( errno ) ); +@@ -1103,7 +1106,7 @@ static int OpenVideoDev( demux_t *p_demu + { + struct video_window vid_win; + +- if( ioctl( i_fd, VIDIOCGWIN, &vid_win ) < 0 ) ++ if( v4l1_ioctl( i_fd, VIDIOCGWIN, &vid_win ) < 0 ) + { + msg_Err( p_demux, "cannot get win (%s)", strerror( errno ) ); + goto vdev_failed; +@@ -1130,7 +1133,7 @@ static int OpenVideoDev( demux_t *p_demu + if( !p_sys->b_mjpeg ) + { + /* set hue/color/.. */ +- if( ioctl( i_fd, VIDIOCGPICT, &p_sys->vid_picture ) == 0 ) ++ if( v4l1_ioctl( i_fd, VIDIOCGPICT, &p_sys->vid_picture ) == 0 ) + { + struct video_picture vid_picture = p_sys->vid_picture; + +@@ -1150,7 +1153,7 @@ static int OpenVideoDev( demux_t *p_demu + { + vid_picture.contrast = p_sys->i_contrast; + } +- if( ioctl( i_fd, VIDIOCSPICT, &vid_picture ) == 0 ) ++ if( v4l1_ioctl( i_fd, VIDIOCSPICT, &vid_picture ) == 0 ) + { + msg_Dbg( p_demux, "v4l device uses brightness: %d", + vid_picture.brightness ); +@@ -1164,7 +1167,7 @@ static int OpenVideoDev( demux_t *p_demu + } + + /* Find out video format used by device */ +- if( ioctl( i_fd, VIDIOCGPICT, &p_sys->vid_picture ) == 0 ) ++ if( v4l1_ioctl( i_fd, VIDIOCGPICT, &p_sys->vid_picture ) == 0 ) + { + struct video_picture vid_picture = p_sys->vid_picture; + char *psz; +@@ -1191,7 +1194,7 @@ static int OpenVideoDev( demux_t *p_demu + free( psz ); + + if( vid_picture.palette && +- !ioctl( i_fd, VIDIOCSPICT, &vid_picture ) ) ++ !v4l1_ioctl( i_fd, VIDIOCSPICT, &vid_picture ) ) + { + p_sys->vid_picture = vid_picture; + } +@@ -1199,14 +1202,14 @@ static int OpenVideoDev( demux_t *p_demu + { + /* Try to set the format to something easy to encode */ + vid_picture.palette = VIDEO_PALETTE_YUV420P; +- if( ioctl( i_fd, VIDIOCSPICT, &vid_picture ) == 0 ) ++ if( v4l1_ioctl( i_fd, VIDIOCSPICT, &vid_picture ) == 0 ) + { + p_sys->vid_picture = vid_picture; + } + else + { + vid_picture.palette = VIDEO_PALETTE_YUV422P; +- if( ioctl( i_fd, VIDIOCSPICT, &vid_picture ) == 0 ) ++ if( v4l1_ioctl( i_fd, VIDIOCSPICT, &vid_picture ) == 0 ) + { + p_sys->vid_picture = vid_picture; + } +@@ -1237,13 +1240,13 @@ static int OpenVideoDev( demux_t *p_demu + p_sys->mjpeg_buffers.count = 8; + p_sys->mjpeg_buffers.size = MJPEG_BUFFER_SIZE; + +- if( ioctl( i_fd, MJPIOC_REQBUFS, &p_sys->mjpeg_buffers ) < 0 ) ++ if( v4l1_ioctl( i_fd, MJPIOC_REQBUFS, &p_sys->mjpeg_buffers ) < 0 ) + { + msg_Err( p_demux, "mmap unsupported" ); + goto vdev_failed; + } + +- p_sys->p_video_mmap = mmap( 0, ++ p_sys->p_video_mmap = v4l1_mmap( 0, + p_sys->mjpeg_buffers.size * p_sys->mjpeg_buffers.count, + PROT_READ | PROT_WRITE, MAP_SHARED, i_fd, 0 ); + if( p_sys->p_video_mmap == MAP_FAILED ) +@@ -1258,7 +1261,7 @@ static int OpenVideoDev( demux_t *p_demu + /* queue up all the frames */ + for( i = 0; i < (int)p_sys->mjpeg_buffers.count; i++ ) + { +- if( ioctl( i_fd, MJPIOC_QBUF_CAPT, &i ) < 0 ) ++ if( v4l1_ioctl( i_fd, MJPIOC_QBUF_CAPT, &i ) < 0 ) + { + msg_Err( p_demux, "unable to queue frame" ); + goto vdev_failed; +@@ -1289,13 +1292,13 @@ static int OpenVideoDev( demux_t *p_demu + (char*)&p_sys->i_fourcc ); + + /* Allocate mmap buffer */ +- if( ioctl( i_fd, VIDIOCGMBUF, &p_sys->vid_mbuf ) < 0 ) ++ if( v4l1_ioctl( i_fd, VIDIOCGMBUF, &p_sys->vid_mbuf ) < 0 ) + { + msg_Err( p_demux, "mmap unsupported" ); + goto vdev_failed; + } + +- p_sys->p_video_mmap = mmap( 0, p_sys->vid_mbuf.size, ++ p_sys->p_video_mmap = v4l1_mmap( 0, p_sys->vid_mbuf.size, + PROT_READ|PROT_WRITE, MAP_SHARED, + i_fd, 0 ); + if( p_sys->p_video_mmap == MAP_FAILED ) +@@ -1310,7 +1313,7 @@ static int OpenVideoDev( demux_t *p_demu + p_sys->vid_mmap.width = p_sys->i_width; + p_sys->vid_mmap.height = p_sys->i_height; + p_sys->vid_mmap.format = p_sys->vid_picture.palette; +- if( ioctl( i_fd, VIDIOCMCAPTURE, &p_sys->vid_mmap ) < 0 ) ++ if( v4l1_ioctl( i_fd, VIDIOCMCAPTURE, &p_sys->vid_mmap ) < 0 ) + { + msg_Warn( p_demux, "%4.4s refused", (char*)&p_sys->i_fourcc ); + msg_Err( p_demux, "chroma selection failed" ); +@@ -1321,7 +1324,7 @@ static int OpenVideoDev( demux_t *p_demu + + vdev_failed: + +- if( i_fd >= 0 ) close( i_fd ); ++ if( i_fd >= 0 ) v4l1_close( i_fd ); + return -1; + } + +@@ -1431,7 +1434,7 @@ static uint8_t *GrabCapture( demux_t *p_ + + p_sys->vid_mmap.frame = (p_sys->i_frame_pos + 1) % p_sys->vid_mbuf.frames; + +- while( ioctl( p_sys->fd_video, VIDIOCMCAPTURE, &p_sys->vid_mmap ) < 0 ) ++ while( v4l1_ioctl( p_sys->fd_video, VIDIOCMCAPTURE, &p_sys->vid_mmap ) < 0 ) + { + if( errno != EAGAIN ) + { +@@ -1447,7 +1450,7 @@ static uint8_t *GrabCapture( demux_t *p_ + msg_Dbg( p_demux, "grab failed, trying again" ); + } + +- while( ioctl(p_sys->fd_video, VIDIOCSYNC, &p_sys->i_frame_pos) < 0 ) ++ while( v4l1_ioctl(p_sys->fd_video, VIDIOCSYNC, &p_sys->i_frame_pos) < 0 ) + { + if( errno != EAGAIN && errno != EINTR ) + { +@@ -1473,7 +1476,7 @@ static uint8_t *GrabMJPEG( demux_t *p_de + /* re-queue the last frame we sync'd */ + if( p_sys->i_frame_pos != -1 ) + { +- while( ioctl( p_sys->fd_video, MJPIOC_QBUF_CAPT, ++ while( v4l1_ioctl( p_sys->fd_video, MJPIOC_QBUF_CAPT, + &p_sys->i_frame_pos ) < 0 ) + { + if( errno != EAGAIN && errno != EINTR ) +@@ -1485,7 +1488,7 @@ static uint8_t *GrabMJPEG( demux_t *p_de + } + + /* sync on the next frame */ +- while( ioctl( p_sys->fd_video, MJPIOC_SYNC, &sync ) < 0 ) ++ while( v4l1_ioctl( p_sys->fd_video, MJPIOC_SYNC, &sync ) < 0 ) + { + if( errno != EAGAIN && errno != EINTR ) + { diff --git a/v4l2-apps/lib/libv4l/appl-patches/xawtv-3.95-fixes.patch b/v4l2-apps/lib/libv4l/appl-patches/xawtv-3.95-fixes.patch new file mode 100644 index 000000000..ccb077be0 --- /dev/null +++ b/v4l2-apps/lib/libv4l/appl-patches/xawtv-3.95-fixes.patch @@ -0,0 +1,29 @@ +--- xawtv-3.95/libng/plugins/drv0-v4l2.c 2005-02-11 18:56:24.000000000 +0100 ++++ xawtv-3.95.new/libng/plugins/drv0-v4l2.c 2008-07-05 21:12:37.000000000 +0200 +@@ -161,7 +161,7 @@ + #define PREFIX "ioctl: " + + static int +-xioctl(int fd, int cmd, void *arg, int mayfail) ++xioctl(int fd, unsigned long int cmd, void *arg, int mayfail) + { + int rc; + +@@ -768,6 +768,7 @@ + /* get it */ + memset(&buf,0,sizeof(buf)); + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ++ buf.memory = V4L2_MEMORY_MMAP; + if (-1 == xioctl(h->fd,VIDIOC_DQBUF,&buf, 0)) + return -1; + h->waiton++; +@@ -813,8 +814,7 @@ + if (-1 == xioctl(h->fd, VIDIOC_QUERYBUF, &h->buf_v4l2[i], 0)) + return -1; + h->buf_me[i].fmt = h->fmt_me; +- h->buf_me[i].size = h->buf_me[i].fmt.bytesperline * +- h->buf_me[i].fmt.height; ++ h->buf_me[i].size = h->buf_v4l2[i].length; + h->buf_me[i].data = mmap(NULL, h->buf_v4l2[i].length, + PROT_READ | PROT_WRITE, MAP_SHARED, + h->fd, h->buf_v4l2[i].m.offset); diff --git a/v4l2-apps/lib/libv4l/include/libv4l1.h b/v4l2-apps/lib/libv4l/include/libv4l1.h new file mode 100644 index 000000000..9036ae869 --- /dev/null +++ b/v4l2-apps/lib/libv4l/include/libv4l1.h @@ -0,0 +1,67 @@ +/* +# (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> + +# 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 __LIBV4L1_H +#define __LIBV4L1_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include <stdio.h> +#include <unistd.h> + +/* Point this to a FILE opened for writing when you want to log error and + status messages to a file, when NULL errors will get send to stderr */ +extern FILE *v4l1_log_file; + +/* Just like your regular open/close/etc, except that when opening a v4l2 + capture only device, full v4l1 emulation is done including emulating the + often not implemented in v4l2 drivers CGMBUF ioctl and v4l1 style mmap call + in userspace. + + Format conversion is done if necessary when capturing. That is if you + (try to) set a capture format which is not supported by the cam, but is + supported by libv4lconvert then SPICT will succeed and on SYNC / read the + data will be converted for you and returned in the request format. + + Note that currently libv4l1 depends on the kernel v4l1 compatibility layer + for: 1) Devices which are not capture only, 2) Emulation of many basic + v4l1 ioctl's which require no driver specific handling. + + Note that no functionality is added to v4l1 devices, so if for example an + obscure v4l1 device is opened which only supports some weird capture format + then libv4l1 will not be of any help (in this case it would be best to get + the driver converted to v4l2, as v4l2 has been designed to include weird + capture formats, like hw specific bayer compression methods). +*/ + +int v4l1_open (const char *file, int oflag, ...); +int v4l1_close(int fd); +int v4l1_dup(int fd); +int v4l1_ioctl (int fd, unsigned long int request, ...); +ssize_t v4l1_read (int fd, void* buffer, size_t n); +void *v4l1_mmap(void *start, size_t length, int prot, int flags, int fd, + __off64_t offset); +int v4l1_munmap(void *_start, size_t length); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/v4l2-apps/lib/libv4l/include/libv4l2.h b/v4l2-apps/lib/libv4l/include/libv4l2.h new file mode 100644 index 000000000..63529cf4b --- /dev/null +++ b/v4l2-apps/lib/libv4l/include/libv4l2.h @@ -0,0 +1,104 @@ +/* +# (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> + +# 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 __LIBV4L2_H +#define __LIBV4L2_H + +#include <stdio.h> +#include <unistd.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Point this to a FILE opened for writing when you want to log error and + status messages to a file, when NULL errors will get send to stderr */ +extern FILE *v4l2_log_file; + +/* Just like your regular open/close/etc, except that format conversion is + done if necessary when capturing. That is if you (try to) set a capture + format which is not supported by the cam, but is supported by libv4lconvert, + then the try_fmt / set_fmt will succeed as if the cam supports the format + and on dqbuf / read the data will be converted for you and returned in + the request format. + + Another difference is that you can make v4l2_read() calls even on devices + which do not support the regular read() method. + + Note that libv4l2 normally does not interfere with enum_fmt, so enum_fmt + will still return the actual formats the hardware supports, and not any + formats which may be emulated on top of that. If you pass the + V4L2_ENABLE_ENUM_FMT_EMULATION flag to v4l2_fd_open (as the v4l2convert.so + wrapper does) then enum_fmt will also report support for the formats to + which conversion is possible. + + Note the device name passed to v4l2_open must be of a video4linux2 device, + if it is anything else (including a video4linux1 device), v4l2_open will + fail. +*/ + +int v4l2_open (const char *file, int oflag, ...); +int v4l2_close(int fd); +int v4l2_dup(int fd); +int v4l2_ioctl (int fd, unsigned long int request, ...); +ssize_t v4l2_read (int fd, void* buffer, size_t n); +void *v4l2_mmap(void *start, size_t length, int prot, int flags, int fd, + __off64_t offset); +int v4l2_munmap(void *_start, size_t length); + + +/* Misc utility functions */ + +/* This function takes a value of 0 - 65535, and then scales that range to + the actual range of the given v4l control id, and then if the cid exists + and is not locked sets the cid to the scaled value. + + Normally returns 0, even if the cid did not exist or was locked, returns + non 0 when an other error occured. */ +int v4l2_set_control(int fd, int cid, int value); + +/* This function returns a value of 0 - 65535, scaled to from the actual range + of the given v4l control id. when the cid does not exist, could not be + accessed for some reason, or some error occured 0 is returned. */ +int v4l2_get_control(int fd, int cid); + + +/* "low level" access functions, these functions allow somewhat lower level + access to libv4l2 (currently there only is v4l2_fd_open here) */ + +/* Flags for v4l2_fd_open's v4l2_flags argument */ + +/* Disable all format conversion done by libv4l2 (reduces libv4l2 functionality + to offering v4l2_read() even on devices which don't implement read()) */ +#define V4L2_DISABLE_CONVERSION 0x01 +/* Report not only real but also emulated formats with the ENUM_FMT ioctl */ +#define V4L2_ENABLE_ENUM_FMT_EMULATION 02 + +/* v4l2_fd_open: open an already opened fd for further use through + v4l2lib and possibly modify libv4l2's default behavior through the + v4l2_flags argument. + + Returns fd on success, -1 if the fd is not suitable for use through libv4l2 + (note the fd is left open in this case). */ +int v4l2_fd_open(int fd, int v4l2_flags); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/v4l2-apps/lib/libv4l/include/libv4lconvert.h b/v4l2-apps/lib/libv4l/include/libv4lconvert.h new file mode 100644 index 000000000..d8446dac8 --- /dev/null +++ b/v4l2-apps/lib/libv4l/include/libv4lconvert.h @@ -0,0 +1,67 @@ +/* +# (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> + +# 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 __LIBV4LCONVERT_H +#define __LIBV4LCONVERT_H + +/* These headers are not needed by us, but by linux/videodev2.h, + which is broken on some systems and doesn't include them itself :( */ +#include <sys/time.h> +#include <linux/types.h> +#include <linux/ioctl.h> +/* end broken header workaround includes */ +#include <linux/videodev2.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +struct v4lconvert_data; + +struct v4lconvert_data *v4lconvert_create(int fd); +void v4lconvert_destroy(struct v4lconvert_data *data); + +/* With regards to dest_fmt just like VIDIOC_TRY_FMT, except that the try + format will succeed and return the requested V4L2_PIX_FMT_foo in dest_fmt if + the cam has a format from which v4lconvert can convert to dest_fmt. + The real format to which the cam should be set is returned through src_fmt + when not NULL. */ +int v4lconvert_try_format(struct v4lconvert_data *data, + struct v4l2_format *dest_fmt, /* in / out */ + struct v4l2_format *src_fmt /* out */ +); + +/* Just like VIDIOC_ENUM_FMT, except that the emulated formats are added at + the end of the list */ +int v4lconvert_enum_fmt(struct v4lconvert_data *data, struct v4l2_fmtdesc *fmt); + +/* return value of -1 on error, otherwise the amount of bytes written to + dest */ +int v4lconvert_convert(struct v4lconvert_data *data, + const struct v4l2_format *src_fmt, /* in */ + const struct v4l2_format *dest_fmt, /* in */ + unsigned char *src, int src_size, unsigned char *dest, int dest_size); + +/* get a string describing the last error*/ +const char *v4lconvert_get_error_message(struct v4lconvert_data *data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/v4l2-apps/lib/libv4l/libv4l1/Makefile b/v4l2-apps/lib/libv4l/libv4l1/Makefile new file mode 100644 index 000000000..8cb064cd4 --- /dev/null +++ b/v4l2-apps/lib/libv4l/libv4l1/Makefile @@ -0,0 +1,56 @@ +CC = gcc +LD = gcc + +CPPFLAGS = -fPIC -I../include -I../../../../linux/include + +CFLAGS := -g -O1 +CFLAGS += -Wall -W -Wno-unused -Wpointer-arith -Wstrict-prototypes + +LDFLAGS = -shared + +V4L1_OBJS = libv4l1.o log.o ../libv4l2/libv4l2.so +V4L1_LIB = libv4l1.so +V4L1COMPAT = v4l1compat.so +V4L1COMPAT_O = v4l1compat.o libv4l1.so +TARGETS = $(V4L1_LIB) $(V4L1COMPAT) +INCLUDES = ../include/libv4l1.h + +ifeq ($(LIB_RELEASE),) +LIB_RELEASE = 0 +endif + +ifeq ($(PREFIX),) +PREFIX = /usr/local +endif + +ifeq ($(LIBDIR),) +LIBDIR = $(PREFIX)/lib +endif + +all: $(TARGETS) + + +$(V4L1_LIB): $(V4L1_OBJS) + +$(V4L1COMPAT): $(V4L1COMPAT_O) $(V4L1_LIB) + +install: all + mkdir -p $(DESTDIR)$(PREFIX)/include + install -p -m 644 $(INCLUDES) $(DESTDIR)$(PREFIX)/include + mkdir -p $(DESTDIR)$(LIBDIR)/libv4l + install -m 755 $(V4L1_LIB).$(LIB_RELEASE) $(DESTDIR)$(LIBDIR) + cd $(DESTDIR)$(LIBDIR) && \ + ln -f -s $(V4L1_LIB).$(LIB_RELEASE) $(V4L1_LIB) + install -m 755 $(V4L1COMPAT).$(LIB_RELEASE) \ + $(DESTDIR)$(LIBDIR)/libv4l/$(V4L1COMPAT) + +clean:: + rm -f *.so* *.o log *~ + rm -f *.d + +%.o: %.c + $(CC) -c -MMD $(CPPFLAGS) $(CFLAGS) -o $@ $< + +%.so: + $(CC) $(LDFLAGS) -Wl,-soname,$@.$(LIB_RELEASE) -o $@.$(LIB_RELEASE) $^ + ln -f -s $@.$(LIB_RELEASE) $@ diff --git a/v4l2-apps/lib/libv4l/libv4l1/libv4l1-priv.h b/v4l2-apps/lib/libv4l/libv4l1/libv4l1-priv.h new file mode 100644 index 000000000..e107581d1 --- /dev/null +++ b/v4l2-apps/lib/libv4l/libv4l1/libv4l1-priv.h @@ -0,0 +1,74 @@ +/* +# (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> + +# 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 __LIBV4L1_PRIV_H +#define __LIBV4L1_PRIV_H + +#include <stdio.h> +#include <pthread.h> + +#define V4L1_MAX_DEVICES 16 +#define V4L1_NO_FRAMES 4 +#define V4L1_FRAME_BUF_SIZE (4096 * 4096) + +extern FILE *v4l1_log_file; + +#define V4L1_LOG_ERR(...) \ + do { \ + if (v4l1_log_file) { \ + fprintf(v4l1_log_file, "libv4l1: error " __VA_ARGS__); \ + fflush(v4l1_log_file); \ + } else \ + fprintf(stderr, "libv4l1: error " __VA_ARGS__); \ + } while(0) + +#define V4L1_LOG_WARN(...) \ + do { \ + if (v4l1_log_file) { \ + fprintf(v4l1_log_file, "libv4l1: warning " __VA_ARGS__); \ + fflush(v4l1_log_file); \ + } else \ + fprintf(stderr, "libv4l1: warning " __VA_ARGS__); \ + } while(0) + +#define V4L1_LOG(...) \ + do { \ + if (v4l1_log_file) { \ + fprintf(v4l1_log_file, "libv4l1: " __VA_ARGS__); \ + fflush(v4l1_log_file); \ + } \ + } while(0) + +struct v4l1_dev_info { + int fd; + int flags; + int open_count; + int v4l1_frame_buf_map_count; + pthread_mutex_t stream_lock; + unsigned int depth; + unsigned int v4l1_pal; /* VIDEO_PALETTE */ + unsigned int v4l2_pixfmt; /* V4L2_PIX_FMT */ + unsigned int min_width, min_height, max_width, max_height; + unsigned int width, height; + unsigned char *v4l1_frame_pointer; +}; + +/* From log.c */ +void v4l1_log_ioctl(unsigned long int request, void *arg, int result); + +#endif diff --git a/v4l2-apps/lib/libv4l/libv4l1/libv4l1.c b/v4l2-apps/lib/libv4l/libv4l1/libv4l1.c new file mode 100644 index 000000000..40e4b2aa1 --- /dev/null +++ b/v4l2-apps/lib/libv4l/libv4l1/libv4l1.c @@ -0,0 +1,831 @@ +/* +# libv4l1 userspace v4l1 api emulation for v4l2 devices + +# (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> + +# 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 +*/ + +/* MAKING CHANGES TO THIS FILE?? READ THIS FIRST!!! + + Important note to people making changes to this file: All functions + (v4l1_close, v4l1_ioctl, etc.) are designed to function as their regular + counterpart when they get passed a fd that is not "registered" by libv4l1, + there are 2 reasons for this: + 1) This allows us to get completely out of the way when dealing with non + capture only devices, or non v4l2 devices. + 2) libv4l1 is the base of the v4l1compat.so wrapper lib, which is a .so + which can be LD_PRELOAD-ed and the overrules the libc's open/close/etc, + and when opening /dev/videoX calls v4l1_open. Because we behave as the + regular counterpart when the fd is not known (instead of say throwing + an error), v4l1compat.so can simply call the v4l1_ prefixed function + for all wrapped functions. This way the wrapper does not have to keep + track of which fd's are being handled by libv4l1, as libv4l1 already + keeps track of this itself. + + This also means that libv4l1 may not use any of the regular functions + it mimics, as for example open could be a symbol in v4l1compat.so, which + in turn will call v4l1_open, so therefor v4l1_open (for example) may not + use the regular open()! +*/ +#include <errno.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <syscall.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/mman.h> +/* These headers are not needed by us, but by linux/videodev2.h, + which is broken on some systems and doesn't include them itself :( */ +#include <sys/time.h> +#include <asm/types.h> +#include <linux/ioctl.h> +/* end broken header workaround includes */ +#include <linux/videodev.h> +#include <linux/videodev2.h> +#include <libv4l2.h> +#include "libv4l1-priv.h" + +#define V4L1_SUPPORTS_ENUMINPUT 0x01 +#define V4L1_SUPPORTS_ENUMSTD 0x02 +#define V4L1_PIX_FMT_TOUCHED 0x04 +#define V4L1_PIX_SIZE_TOUCHED 0x08 + +static pthread_mutex_t v4l1_open_mutex = PTHREAD_MUTEX_INITIALIZER; +static struct v4l1_dev_info devices[V4L1_MAX_DEVICES] = { { .fd = -1 }, + { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, + { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, + { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 }}; +static int devices_used = 0; + +static unsigned int palette_to_pixelformat(unsigned int palette) +{ + switch (palette) { + case VIDEO_PALETTE_GREY: + return V4L2_PIX_FMT_GREY; + case VIDEO_PALETTE_RGB555: + return V4L2_PIX_FMT_RGB555; + case VIDEO_PALETTE_RGB565: + return V4L2_PIX_FMT_RGB565; + case VIDEO_PALETTE_RGB24: + return V4L2_PIX_FMT_BGR24; + case VIDEO_PALETTE_RGB32: + return V4L2_PIX_FMT_BGR32; + case VIDEO_PALETTE_YUYV: + return V4L2_PIX_FMT_YUYV; + case VIDEO_PALETTE_YUV422: + return V4L2_PIX_FMT_YUYV; + case VIDEO_PALETTE_UYVY: + return V4L2_PIX_FMT_UYVY; + case VIDEO_PALETTE_YUV410P: + return V4L2_PIX_FMT_YUV410; + case VIDEO_PALETTE_YUV420: + case VIDEO_PALETTE_YUV420P: + return V4L2_PIX_FMT_YUV420; + case VIDEO_PALETTE_YUV411P: + return V4L2_PIX_FMT_YUV411P; + case VIDEO_PALETTE_YUV422P: + return V4L2_PIX_FMT_YUV422P; + } + return 0; +} + +static unsigned int pixelformat_to_palette(unsigned int pixelformat) +{ + switch (pixelformat) { + case V4L2_PIX_FMT_GREY: + return VIDEO_PALETTE_GREY; + case V4L2_PIX_FMT_RGB555: + return VIDEO_PALETTE_RGB555; + case V4L2_PIX_FMT_RGB565: + return VIDEO_PALETTE_RGB565; + case V4L2_PIX_FMT_BGR24: + return VIDEO_PALETTE_RGB24; + case V4L2_PIX_FMT_BGR32: + return VIDEO_PALETTE_RGB32; + case V4L2_PIX_FMT_YUYV: + return VIDEO_PALETTE_YUYV; + case V4L2_PIX_FMT_UYVY: + return VIDEO_PALETTE_UYVY; + case V4L2_PIX_FMT_YUV410: + case V4L2_PIX_FMT_YUV420: + return VIDEO_PALETTE_YUV420P; + case V4L2_PIX_FMT_YUV411P: + return VIDEO_PALETTE_YUV411P; + case V4L2_PIX_FMT_YUV422P: + return VIDEO_PALETTE_YUV422P; + } + return 0; +} + +static int v4l1_set_format(int index, unsigned int width, + unsigned int height, int v4l1_pal, int width_height_may_differ) +{ + int result; + unsigned int v4l2_pixfmt; + struct v4l2_format fmt2 = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE }; + + if (v4l1_pal != -1) { + v4l2_pixfmt = palette_to_pixelformat(v4l1_pal); + if (!v4l2_pixfmt) { + V4L1_LOG("Unknown v4l1 palette number: %d\n", v4l1_pal); + errno = EINVAL; + return -1; + } + } else { + v4l2_pixfmt = devices[index].v4l2_pixfmt; + v4l1_pal = devices[index].v4l1_pal; + } + + /* Do we need to change the resolution / format ? */ + if (width == devices[index].width && height == devices[index].height && + v4l2_pixfmt == devices[index].v4l2_pixfmt) + return 0; + + /* Get current settings, apply our changes and try the new setting */ + if ((result = v4l2_ioctl(devices[index].fd, VIDIOC_G_FMT, &fmt2))) { + int saved_err = errno; + V4L1_LOG_ERR("getting pixformat: %s\n", strerror(errno)); + errno = saved_err; + return result; + } + + fmt2.fmt.pix.pixelformat = v4l2_pixfmt; + fmt2.fmt.pix.width = width; + fmt2.fmt.pix.height = height; + if ((result = v4l2_ioctl(devices[index].fd, VIDIOC_TRY_FMT, &fmt2))) + { + int saved_err = errno; + V4L1_LOG("error trying pixformat: %s\n", strerror(errno)); + errno = saved_err; + return result; + } + + /* Check if we get what we asked for */ + if (fmt2.fmt.pix.pixelformat != v4l2_pixfmt || (!width_height_may_differ && + (fmt2.fmt.pix.width != width || fmt2.fmt.pix.height != height))) { + V4L1_LOG("requested fmt, width, height combo not available\n"); + errno = EINVAL; + return -1; + } + + /* Maybe after the TRY_FMT things haven't changed after all ? */ + if (fmt2.fmt.pix.width == devices[index].width && + fmt2.fmt.pix.height == devices[index].height && + fmt2.fmt.pix.pixelformat == devices[index].v4l2_pixfmt) { + devices[index].v4l1_pal = v4l1_pal; + return 0; + } + + if ((result = v4l2_ioctl(devices[index].fd, VIDIOC_S_FMT, &fmt2))) { + int saved_err = errno; + V4L1_LOG_ERR("setting pixformat: %s\n", strerror(errno)); + errno = saved_err; + return result; + } + + devices[index].width = fmt2.fmt.pix.width; + devices[index].height = fmt2.fmt.pix.height; + devices[index].v4l2_pixfmt = v4l2_pixfmt; + devices[index].v4l1_pal = v4l1_pal; + devices[index].depth = ((fmt2.fmt.pix.bytesperline << 3) + + (fmt2.fmt.pix.width - 1)) / fmt2.fmt.pix.width; + + return result; +} + +static void v4l1_find_min_and_max_size(int index, struct v4l2_format *fmt2) +{ + int i; + struct v4l2_fmtdesc fmtdesc2 = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE }; + + devices[index].min_width = -1; + devices[index].min_height = -1; + devices[index].max_width = 0; + devices[index].max_height = 0; + + for (i = 0; ; i++) { + fmtdesc2.index = i; + + if (syscall(SYS_ioctl, devices[index].fd, VIDIOC_ENUM_FMT, &fmtdesc2)) + break; + + fmt2->fmt.pix.pixelformat = fmtdesc2.pixelformat; + fmt2->fmt.pix.width = 48; + fmt2->fmt.pix.height = 32; + + if (syscall(SYS_ioctl, devices[index].fd, VIDIOC_TRY_FMT, fmt2) == 0) { + if (fmt2->fmt.pix.width < devices[index].min_width) + devices[index].min_width = fmt2->fmt.pix.width; + if (fmt2->fmt.pix.height < devices[index].min_height) + devices[index].min_height = fmt2->fmt.pix.height; + } + + fmt2->fmt.pix.pixelformat = fmtdesc2.pixelformat; + fmt2->fmt.pix.width = 100000; + fmt2->fmt.pix.height = 100000; + + if (syscall(SYS_ioctl, devices[index].fd, VIDIOC_TRY_FMT, fmt2) == 0) { + if (fmt2->fmt.pix.width > devices[index].max_width) + devices[index].max_width = fmt2->fmt.pix.width; + if (fmt2->fmt.pix.height > devices[index].max_height) + devices[index].max_height = fmt2->fmt.pix.height; + } + } +} + + +int v4l1_open (const char *file, int oflag, ...) +{ + int index, fd; + char *lfname; + struct v4l2_capability cap2; + struct v4l2_format fmt2; + struct v4l2_input input2; + struct v4l2_standard standard2; + + /* original open code */ + if (oflag & O_CREAT) + { + va_list ap; + mode_t mode; + + va_start (ap, oflag); + mode = va_arg (ap, mode_t); + + fd = syscall(SYS_open, file, oflag, mode); + + va_end(ap); + } else + fd = syscall(SYS_open, file, oflag); + /* end of original open code */ + + if (fd == -1) + return fd; + + /* check if we're opening a video4linux2 device */ + if (strncmp(file, "/dev/video", 10)) + return fd; + + /* check that this is an v4l2 device, no need to emulate v4l1 on + a v4l1 device */ + if (syscall(SYS_ioctl, fd, VIDIOC_QUERYCAP, &cap2)) + return fd; + + /* IMPROVEME */ + /* we only support simple video capture devices which do not do overlay */ + if ((cap2.capabilities & 0x0F) != V4L2_CAP_VIDEO_CAPTURE) + return fd; + + /* If no log file was set by the app, see if one was specified through the + environment */ + if (!v4l1_log_file && (lfname = getenv("LIBV4L1_LOG_FILENAME"))) + v4l1_log_file = fopen(lfname, "w"); + + /* redirect libv4l2 log messages to our logfile if no libv4l2 logfile is + specified */ + if (!v4l2_log_file) + v4l2_log_file = v4l1_log_file; + + /* Get initial width, height and pixelformat */ + fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (syscall(SYS_ioctl, fd, VIDIOC_G_FMT, &fmt2)) { + int saved_err = errno; + V4L1_LOG_ERR("getting pixformat: %s\n", strerror(errno)); + syscall(SYS_close, fd); + errno = saved_err; + return -1; + } + + /* Register with libv4l2, as we use that todo format conversion and read() + emulation for us */ + if (v4l2_fd_open(fd, V4L2_ENABLE_ENUM_FMT_EMULATION) == -1) { + int saved_err = errno; + syscall(SYS_close, fd); + errno = saved_err; + return -1; + } + + /* So we have a device on which we can (and want to) emulate v4l1, register + it in our devices array */ + pthread_mutex_lock(&v4l1_open_mutex); + for (index = 0; index < V4L1_MAX_DEVICES; index++) + if(devices[index].fd == -1) { + devices[index].fd = fd; + break; + } + pthread_mutex_unlock(&v4l1_open_mutex); + + if (index == V4L1_MAX_DEVICES) { + V4L1_LOG_ERR("attempting to open more then %d video devices\n", + V4L1_MAX_DEVICES); + v4l2_close(fd); + errno = EBUSY; + return -1; + } + + if (index >= devices_used) + devices_used = index + 1; + + devices[index].flags = 0; + devices[index].open_count = 1; + devices[index].v4l1_frame_buf_map_count = 0; + devices[index].v4l1_frame_pointer = MAP_FAILED; + devices[index].width = fmt2.fmt.pix.width; + devices[index].height = fmt2.fmt.pix.height; + devices[index].v4l2_pixfmt = fmt2.fmt.pix.pixelformat; + devices[index].v4l1_pal = pixelformat_to_palette(fmt2.fmt.pix.pixelformat); + devices[index].depth = ((fmt2.fmt.pix.bytesperline << 3) + + (fmt2.fmt.pix.width - 1)) / fmt2.fmt.pix.width; + + v4l1_find_min_and_max_size(index, &fmt2); + + /* Check ENUM_INPUT and ENUM_STD support */ + input2.index = 0; + if (v4l2_ioctl(fd, VIDIOC_ENUMINPUT, &input2) == 0) + devices[index].flags |= V4L1_SUPPORTS_ENUMINPUT; + + standard2.index = 0; + if (v4l2_ioctl(fd, VIDIOC_ENUMSTD, &input2) == 0) + devices[index].flags |= V4L1_SUPPORTS_ENUMSTD; + + V4L1_LOG("open: %d\n", fd); + + return fd; +} + +/* Is this an fd for which we are emulating v4l1 ? */ +static int v4l1_get_index(int fd) +{ + int index; + + /* We never handle fd -1 */ + if (fd == -1) + return -1; + + for (index = 0; index < devices_used; index++) + if (devices[index].fd == fd) + break; + + if (index == devices_used) + return -1; + + return index; +} + + +int v4l1_close(int fd) { + int index, result; + + if ((index = v4l1_get_index(fd)) == -1) + return syscall(SYS_close, fd); + + /* Abuse stream_lock to stop 2 closes from racing and trying to free the + resources twice */ + pthread_mutex_lock(&devices[index].stream_lock); + devices[index].open_count--; + result = devices[index].open_count != 0; + pthread_mutex_unlock(&devices[index].stream_lock); + + if (result) + return v4l2_close(fd); + + /* Free resources */ + if (devices[index].v4l1_frame_pointer != MAP_FAILED) { + if (devices[index].v4l1_frame_buf_map_count) + V4L1_LOG("v4l1 capture buffer still mapped: %d times on close()\n", + devices[index].v4l1_frame_buf_map_count); + else + syscall(SYS_munmap, devices[index].v4l1_frame_pointer, + V4L1_NO_FRAMES * V4L1_FRAME_BUF_SIZE); + devices[index].v4l1_frame_pointer = MAP_FAILED; + } + + /* Remove the fd from our list of managed fds before closing it, because as + soon as we've done the actual close the fd maybe returned by an open in + another thread and we don't want to intercept calls to this new fd. */ + devices[index].fd = -1; + + result = v4l2_close(fd); + + V4L1_LOG("close: %d\n", fd); + + return result; +} + +int v4l1_dup(int fd) +{ + int index; + + if ((index = v4l1_get_index(fd)) == -1) + return syscall(SYS_dup, fd); + + devices[index].open_count++; + + return v4l2_dup(fd); +} + + +int v4l1_ioctl (int fd, unsigned long int request, ...) +{ + void *arg; + va_list ap; + int result, index, saved_err, stream_locked = 0; + + va_start (ap, request); + arg = va_arg (ap, void *); + va_end (ap); + + if ((index = v4l1_get_index(fd)) == -1) + return syscall(SYS_ioctl, fd, request, arg); + + /* Appearantly the kernel and / or glibc ignore the 32 most significant bits + when long = 64 bits, and some applications pass an int holding the req to + ioctl, causing it to get sign extended, depending upon this behavior */ + request = (unsigned int)request; + + /* do we need to take the stream lock for this ioctl? */ + switch (request) { + case VIDIOCSPICT: + case VIDIOCGPICT: + case VIDIOCSWIN: + case VIDIOCGWIN: + case VIDIOCGMBUF: + case VIDIOCMCAPTURE: + case VIDIOCSYNC: + case VIDIOC_S_FMT: + pthread_mutex_lock(&devices[index].stream_lock); + stream_locked = 1; + } + + switch (request) { + + case VIDIOCGCAP: + { + struct video_capability *cap = arg; + + result = syscall(SYS_ioctl, fd, request, arg); + + /* override kernel v4l1 compat min / max size with our own more + accurate values */ + cap->minwidth = devices[index].min_width; + cap->minheight = devices[index].min_height; + cap->maxwidth = devices[index].max_width; + cap->maxheight = devices[index].max_height; + } + break; + + case VIDIOCSPICT: + { + struct video_picture *pic = arg; + + devices[index].flags |= V4L1_PIX_FMT_TOUCHED; + + v4l2_set_control(fd, V4L2_CID_BRIGHTNESS, pic->brightness); + v4l2_set_control(fd, V4L2_CID_HUE, pic->hue); + v4l2_set_control(fd, V4L2_CID_CONTRAST, pic->contrast); + v4l2_set_control(fd, V4L2_CID_SATURATION, pic->colour); + v4l2_set_control(fd, V4L2_CID_WHITENESS, pic->whiteness); + + result = v4l1_set_format(index, devices[index].width, + devices[index].height, pic->palette, 0); + } + break; + + case VIDIOCGPICT: + { + struct video_picture *pic = arg; + + /* If our v4l2 pixformat has no corresponding v4l1 palette, and the + app has not touched the pixformat sofar, try setting a palette which + does (and which we emulate when necessary) so that applications + which just query the current format and then take whatever they get + will work */ + if (!(devices[index].flags & V4L1_PIX_FMT_TOUCHED) && + !pixelformat_to_palette(devices[index].v4l2_pixfmt)) + v4l1_set_format(index, devices[index].width, + devices[index].height, + VIDEO_PALETTE_RGB24, + (devices[index].flags & + V4L1_PIX_SIZE_TOUCHED) ? 0 : 1); + + devices[index].flags |= V4L1_PIX_FMT_TOUCHED; + + pic->depth = devices[index].depth; + pic->palette = devices[index].v4l1_pal; + pic->hue = v4l2_get_control(devices[index].fd, V4L2_CID_HUE); + pic->colour = v4l2_get_control(devices[index].fd, V4L2_CID_SATURATION); + pic->contrast = v4l2_get_control(devices[index].fd, V4L2_CID_CONTRAST); + pic->whiteness = v4l2_get_control(devices[index].fd, + V4L2_CID_WHITENESS); + pic->brightness = v4l2_get_control(devices[index].fd, + V4L2_CID_BRIGHTNESS); + + result = 0; + } + break; + + case VIDIOCSWIN: + { + struct video_window *win = arg; + + devices[index].flags |= V4L1_PIX_SIZE_TOUCHED; + + result = v4l1_set_format(index, win->width, win->height, -1, 1); + if (result == 0) { + win->width = devices[index].width; + win->height = devices[index].height; + } + } + break; + + case VIDIOCGWIN: + devices[index].flags |= V4L1_PIX_SIZE_TOUCHED; + result = syscall(SYS_ioctl, fd, request, arg); + break; + + case VIDIOCGCHAN: + { + struct v4l2_input input2; + struct video_channel *chan = arg; + + if ((devices[index].flags & V4L1_SUPPORTS_ENUMINPUT) && + (devices[index].flags & V4L1_SUPPORTS_ENUMSTD)) { + result = syscall(SYS_ioctl, fd, request, arg); + break; + } + + /* Set some defaults */ + chan->tuners = 0; + chan->flags = 0; + chan->type = VIDEO_TYPE_CAMERA; + chan->norm = 0; + + /* In case of no ENUMSTD support, ignore the norm member of the + channel struct */ + if (devices[index].flags & V4L1_SUPPORTS_ENUMINPUT) { + input2.index = chan->channel; + result = v4l2_ioctl(fd, VIDIOC_ENUMINPUT, &input2); + if (result == 0) { + snprintf(chan->name, sizeof(chan->name), "%s", input2.name); + if (input2.type == V4L2_INPUT_TYPE_TUNER) { + chan->tuners = 1; + chan->type = VIDEO_TYPE_TV; + chan->flags = VIDEO_VC_TUNER; + } + } + break; + } + + /* No ENUMINPUT support, fake it (assume its a Camera in this case) */ + if (chan->channel == 0) { + snprintf(chan->name, sizeof(chan->name), "Camera"); + result = 0; + } else { + errno = EINVAL; + result = -1; + } + } + break; + + case VIDIOCSCHAN: + { + struct video_channel *chan = arg; + if ((devices[index].flags & V4L1_SUPPORTS_ENUMINPUT) && + (devices[index].flags & V4L1_SUPPORTS_ENUMSTD)) { + result = syscall(SYS_ioctl, fd, request, arg); + break; + } + /* In case of no ENUMSTD support, ignore the norm member of the + channel struct */ + if (devices[index].flags & V4L1_SUPPORTS_ENUMINPUT) { + result = v4l2_ioctl(fd, VIDIOC_S_INPUT, &chan->channel); + break; + } + /* No ENUMINPUT support, fake it (assume its a Camera in this case) */ + if (chan->channel == 0) { + result = 0; + } else { + errno = EINVAL; + result = -1; + } + } + break; + + case VIDIOCGMBUF: + /* When VIDIOCGMBUF is done, we don't necessarrily know the format the + application wants yet (with some apps this is passed for the first + time through VIDIOCMCAPTURE), so we just create an anonymous mapping + that should be large enough to hold any sort of frame. Note this only + takes virtual memory, and does not use memory until actually used. */ + { + int i; + struct video_mbuf *mbuf = arg; + + mbuf->size = V4L1_NO_FRAMES * V4L1_FRAME_BUF_SIZE; + mbuf->frames = V4L1_NO_FRAMES; + for (i = 0; i < mbuf->frames; i++) { + mbuf->offsets[i] = i * V4L1_FRAME_BUF_SIZE; + } + + if (devices[index].v4l1_frame_pointer == MAP_FAILED) { + devices[index].v4l1_frame_pointer = (void *)syscall(SYS_mmap, NULL, + (size_t)mbuf->size, + PROT_READ|PROT_WRITE, + MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); + if (devices[index].v4l1_frame_pointer == MAP_FAILED) { + saved_err = errno; + V4L1_LOG_ERR("allocating v4l1 buffer: %s\n", strerror(errno)); + errno = saved_err; + result = -1; + break; + } + V4L1_LOG("allocated v4l1 buffer @ %p\n", + devices[index].v4l1_frame_pointer); + } + result = 0; + } + break; + + case VIDIOCMCAPTURE: + { + struct video_mmap *map = arg; + + devices[index].flags |= V4L1_PIX_FMT_TOUCHED | + V4L1_PIX_SIZE_TOUCHED; + + result = v4l1_set_format(index, map->width, map->height, + map->format, 0); + } + break; + + case VIDIOCSYNC: + { + int *frame_index = arg; + + if (devices[index].v4l1_frame_pointer == MAP_FAILED || + *frame_index < 0 || *frame_index >= V4L1_NO_FRAMES) { + errno = EINVAL; + result = -1; + break; + } + + result = v4l2_read(devices[index].fd, + devices[index].v4l1_frame_pointer + + *frame_index * V4L1_FRAME_BUF_SIZE, + V4L1_FRAME_BUF_SIZE); + result = (result > 0) ? 0:result; + } + break; + + /* We are passing through v4l2 calls to libv4l2 for applications which are + using v4l2 through libv4l1 (possible with the v4l1compat.so wrapper). + + So the application could be calling VIDIOC_S_FMT, in this case update + our own bookkeeping of the cam's format. Note that this really only is + relevant if an application is mixing and matching v4l1 and v4l2 calls, + which is crazy, but better safe then sorry. */ + case VIDIOC_S_FMT: + { + struct v4l2_format *fmt2 = arg; + + result = v4l2_ioctl(fd, request, arg); + + if (result == 0 && fmt2->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { + if (devices[index].v4l2_pixfmt != fmt2->fmt.pix.pixelformat) { + devices[index].v4l2_pixfmt = fmt2->fmt.pix.pixelformat; + devices[index].v4l1_pal = + pixelformat_to_palette(fmt2->fmt.pix.pixelformat); + } + devices[index].width = fmt2->fmt.pix.width; + devices[index].height = fmt2->fmt.pix.height; + } + } + break; + + default: + /* Pass through libv4l2 for applications which are using v4l2 through + libv4l1 (this can happen with the v4l1compat.so wrapper preloaded */ + result = v4l2_ioctl(fd, request, arg); + } + + if (stream_locked) + pthread_mutex_unlock(&devices[index].stream_lock); + + saved_err = errno; + v4l1_log_ioctl(request, arg, result); + errno = saved_err; + + return result; +} + + +ssize_t v4l1_read(int fd, void* buffer, size_t n) +{ + int index; + ssize_t result; + + if ((index = v4l1_get_index(fd)) == -1) + return syscall(SYS_read, fd, buffer, n); + + pthread_mutex_lock(&devices[index].stream_lock); + result = v4l2_read(fd, buffer, n); + pthread_mutex_unlock(&devices[index].stream_lock); + + return result; +} + + +void *v4l1_mmap(void *start, size_t length, int prot, int flags, int fd, + __off64_t offset) +{ + int index; + void *result; + + /* Check if the mmap data matches our answer to VIDIOCGMBUF, if not + pass through libv4l2 for applications which are using v4l2 through + libv4l1 (this can happen with the v4l1compat.so wrapper preloaded */ + if ((index = v4l1_get_index(fd)) == -1 || start || offset || + length != (V4L1_NO_FRAMES * V4L1_FRAME_BUF_SIZE)) + return v4l2_mmap(start, length, prot, flags, fd, offset); + + + pthread_mutex_lock(&devices[index].stream_lock); + + /* It could be that we get called with an mmap which seems to match what + we expect, but no VIDIOCGMBUF has been done yet, then it is certainly not + for us so pass it through */ + if (devices[index].v4l1_frame_pointer == MAP_FAILED) { + result = v4l2_mmap(start, length, prot, flags, fd, offset); + goto leave; + } + + devices[index].v4l1_frame_buf_map_count++; + + V4L1_LOG("v4l1 buffer @ %p mapped by application\n", + devices[index].v4l1_frame_pointer); + + result = devices[index].v4l1_frame_pointer; + +leave: + pthread_mutex_unlock(&devices[index].stream_lock); + + return result; +} + +int v4l1_munmap(void *_start, size_t length) +{ + int index; + unsigned char *start = _start; + + /* Is this memory ours? */ + if (start != MAP_FAILED && + length == (V4L1_FRAME_BUF_SIZE * V4L1_NO_FRAMES)) { + for (index = 0; index < devices_used; index++) + if (devices[index].fd != -1 && + start == devices[index].v4l1_frame_pointer) + break; + + if (index != devices_used) { + int unmapped = 0; + + pthread_mutex_lock(&devices[index].stream_lock); + + /* Redo our checks now that we have the lock, things may have changed */ + if (start == devices[index].v4l1_frame_pointer) { + if (devices[index].v4l1_frame_buf_map_count > 0) + devices[index].v4l1_frame_buf_map_count--; + + unmapped = 1; + } + + pthread_mutex_unlock(&devices[index].stream_lock); + + if (unmapped) { + V4L1_LOG("v4l1 buffer munmap %p, %d\n", start, (int)length); + return 0; + } + } + } + + V4L1_LOG("v4l1 unknown munmap %p, %d\n", start, (int)length); + + /* If not pass through libv4l2 for applications which are using v4l2 through + libv4l1 (this can happen with the v4l1compat.so wrapper preloaded */ + return v4l2_munmap(start, length); +} diff --git a/v4l2-apps/lib/libv4l/libv4l1/log.c b/v4l2-apps/lib/libv4l/libv4l1/log.c new file mode 100644 index 000000000..178c6d23c --- /dev/null +++ b/v4l2-apps/lib/libv4l/libv4l1/log.c @@ -0,0 +1,138 @@ +/* +# (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> + +# 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 +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <linux/ioctl.h> +/* These headers are not needed by us, but by linux/videodev2.h, + which is broken on some systems and doesn't include them itself :( */ +#include <sys/time.h> +#include <asm/types.h> +/* end broken header workaround includes */ +#include <linux/videodev.h> + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) + +FILE *v4l1_log_file = NULL; + +static const char *v4l1_ioctls[] = { + [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP", + [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN", + [_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN", + [_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER", + [_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER", + [_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT", + [_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT", + [_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE", + [_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN", + [_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN", + [_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF", + [_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF", + [_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY", + [_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ", + [_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ", + [_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO", + [_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO", + [_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC", + [_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE", + [_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF", + [_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT", + [_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE", + [_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE", + [_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE", + [_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE", + [_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO", + [_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE", + [_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT", + [_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT", +}; + +void v4l1_log_ioctl(unsigned long int request, void *arg, int result) +{ + const char *ioctl_str = "unknown"; + + if (!v4l1_log_file) + return; + + /* Don't log v4l2 ioctl's as unknown we pass them to libv4l2 which will + log them for us */ + if (_IOC_TYPE(request) == 'V') + return; + + if (_IOC_TYPE(request) == 'v' && _IOC_NR(request) < ARRAY_SIZE(v4l1_ioctls)) + ioctl_str = v4l1_ioctls[_IOC_NR(request)]; + + fprintf(v4l1_log_file, "request == %s\n", ioctl_str); + + switch(request) + { + case VIDIOCGCAP:fprintf(v4l1_log_file,"name %s\n",( (struct video_capability*)arg)->name ); + fprintf(v4l1_log_file,"type %d\n",( (struct video_capability*)arg)->type ); + fprintf(v4l1_log_file,"channels %d\n",( (struct video_capability*)arg)->channels ); + fprintf(v4l1_log_file,"audios %d\n",( (struct video_capability*)arg)->audios ); + fprintf(v4l1_log_file,"maxwidth %d\n",( (struct video_capability*)arg)->maxwidth ); + fprintf(v4l1_log_file,"maxheight %d\n",( (struct video_capability*)arg)->maxheight ); + fprintf(v4l1_log_file,"minwidth %d\n",( (struct video_capability*)arg)->minwidth ); + fprintf(v4l1_log_file,"minheight %d\n",( (struct video_capability*)arg)->minheight ); + break; + case VIDIOCGWIN: + case VIDIOCSWIN: + fprintf(v4l1_log_file,"width\t%d\n", + ((struct video_window *)arg)->width); + fprintf(v4l1_log_file,"height\t%d\n", + ((struct video_window *)arg)->height); + break; + + case VIDIOCGCHAN: + case VIDIOCSCHAN: + fprintf(v4l1_log_file,"channel %d\n",( (struct video_channel*)arg)->channel ); + fprintf(v4l1_log_file,"name %s\n",( (struct video_channel*)arg)->name ); + break; + + case VIDIOCGPICT: + case VIDIOCSPICT: + fprintf(v4l1_log_file,"brightness %d\n",( (int)((struct video_picture*)arg)->brightness) ); + fprintf(v4l1_log_file,"hue %d\n",( (int)((struct video_picture*)arg)->hue) ); + fprintf(v4l1_log_file,"colour %d\n",( (int)((struct video_picture*)arg)->colour) ); + fprintf(v4l1_log_file,"contrast %d\n",( (int)((struct video_picture*)arg)->contrast) ); + fprintf(v4l1_log_file,"whiteness %d\n",( (int)((struct video_picture*)arg)->whiteness) ); + fprintf(v4l1_log_file,"depth %d\n",( (int)((struct video_picture*)arg)->depth) ); + fprintf(v4l1_log_file,"palette %d\n",( (int)((struct video_picture*)arg)->palette) ); + break; + + case VIDIOCCAPTURE: fprintf(v4l1_log_file,"on/of? %d\n", *((int *)arg) ); + break; + + case VIDIOCSYNC: fprintf(v4l1_log_file,"sync %d\n", *((int *)arg) ); + break; + + case VIDIOCMCAPTURE: + fprintf(v4l1_log_file,"frame %u\n",( (struct video_mmap*)arg)->frame ); + fprintf(v4l1_log_file,"width %d\n",( (struct video_mmap*)arg)->width ); + fprintf(v4l1_log_file,"height %d\n",( (struct video_mmap*)arg)->height ); + fprintf(v4l1_log_file,"format %u\n",( (struct video_mmap*)arg)->format ); + break; + + case VIDIOCGMBUF: + fprintf(v4l1_log_file,"size %d\n",( (struct video_mbuf*)arg)->size ); + fprintf(v4l1_log_file,"frames %d\n",( (struct video_mbuf*)arg)->frames ); + break; + } + fprintf(v4l1_log_file, "result == %d\n", result); + fflush(v4l1_log_file); +} diff --git a/v4l2-apps/lib/libv4l/libv4l1/v4l1compat.c b/v4l2-apps/lib/libv4l/libv4l1/v4l1compat.c new file mode 100644 index 000000000..db3a0027b --- /dev/null +++ b/v4l2-apps/lib/libv4l/libv4l1/v4l1compat.c @@ -0,0 +1,117 @@ +/* +# open/close/ioctl/mmap/munmap library call wrapper doing v4l1 api emulation +# for v4l2 devices + +# (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> + +# 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 +*/ + +#define _LARGEFILE64_SOURCE 1 + +#include <stdlib.h> +#include <stdarg.h> +#include <fcntl.h> +#include <libv4l1.h> + +/* Check that open/read/mmap is not a define */ +#if defined open || defined read || defined mmap +#error open/read/mmap is a prepocessor macro !! +#endif + +int open (const char *file, int oflag, ...) +{ + int fd; + + if (oflag & O_CREAT) + { + va_list ap; + mode_t mode; + + va_start (ap, oflag); + mode = va_arg (ap, mode_t); + + fd = v4l1_open(file, oflag, mode); + + va_end(ap); + } else + fd = v4l1_open(file, oflag); + + return fd; +} + +int open64 (const char *file, int oflag, ...) +{ + int fd; + + if (oflag & O_CREAT) + { + va_list ap; + mode_t mode; + + va_start (ap, oflag); + mode = va_arg (ap, mode_t); + + fd = v4l1_open(file, oflag | O_LARGEFILE, mode); + + va_end(ap); + } else + fd = v4l1_open(file, oflag | O_LARGEFILE); + + return fd; +} + +int close(int fd) { + return v4l1_close(fd); +} + +int dup(int fd) +{ + return v4l1_dup(fd); +} + +int ioctl (int fd, unsigned long int request, ...) +{ + void *arg; + va_list ap; + + va_start (ap, request); + arg = va_arg (ap, void *); + va_end (ap); + + return v4l1_ioctl (fd, request, arg); +} + +ssize_t read(int fd, void* buffer, size_t n) +{ + return v4l1_read (fd, buffer, n); +} + +void mmap(void *start, size_t length, int prot, int flags, int fd, + __off_t offset) +{ + return v4l1_mmap(start, length, prot, flags, fd, offset); +} + +void mmap64(void *start, size_t length, int prot, int flags, int fd, + __off64_t offset) +{ + return v4l1_mmap(start, length, prot, flags, fd, offset); +} + +int munmap(void *start, size_t length) +{ + return v4l1_munmap(start, length); +} diff --git a/v4l2-apps/lib/libv4l/libv4l2/Makefile b/v4l2-apps/lib/libv4l/libv4l2/Makefile new file mode 100644 index 000000000..1258e379b --- /dev/null +++ b/v4l2-apps/lib/libv4l/libv4l2/Makefile @@ -0,0 +1,55 @@ +CC = gcc +LD = gcc + +CPPFLAGS = -fPIC -I../include -I../../../../linux/include + +CFLAGS := -g -O1 +CFLAGS += -Wall -W -Wno-unused -Wpointer-arith -Wstrict-prototypes + +LDFLAGS = -shared + +V4L2_OBJS = libv4l2.o log.o ../libv4lconvert/libv4lconvert.so +V4L2_LIB = libv4l2.so +V4L2CONVERT = v4l2convert.so +V4L2CONVERT_O = v4l2convert.o libv4l2.so +TARGETS = $(V4L2_LIB) $(V4L2CONVERT) +INCLUDES = ../include/libv4l2.h + +ifeq ($(LIB_RELEASE),) +LIB_RELEASE = 0 +endif + +ifeq ($(PREFIX),) +PREFIX = /usr/local +endif + +ifeq ($(LIBDIR),) +LIBDIR = $(PREFIX)/lib +endif + +all: $(TARGETS) + +$(V4L2_LIB): $(V4L2_OBJS) + +$(V4L2CONVERT): $(V4L2CONVERT_O) $(V4L2_LIB) + +install: all + mkdir -p $(DESTDIR)$(PREFIX)/include + install -p -m 644 $(INCLUDES) $(DESTDIR)$(PREFIX)/include + mkdir -p $(DESTDIR)$(LIBDIR)/libv4l + install -m 755 $(V4L2_LIB).$(LIB_RELEASE) $(DESTDIR)$(LIBDIR) + cd $(DESTDIR)$(LIBDIR) && \ + ln -f -s $(V4L2_LIB).$(LIB_RELEASE) $(V4L2_LIB) + install -m 755 $(V4L2CONVERT).$(LIB_RELEASE) \ + $(DESTDIR)$(LIBDIR)/libv4l/$(V4L2CONVERT) + +clean:: + rm -f *.so* *.o log *~ + rm -f *.d + +%.o: %.c + $(CC) -c -MMD $(CPPFLAGS) $(CFLAGS) -o $@ $< + +%.so: + $(CC) $(LDFLAGS) -Wl,-soname,$@.$(LIB_RELEASE) -o $@.$(LIB_RELEASE) $^ + ln -f -s $@.$(LIB_RELEASE) $@ diff --git a/v4l2-apps/lib/libv4l/libv4l2/libv4l2-priv.h b/v4l2-apps/lib/libv4l/libv4l2/libv4l2-priv.h new file mode 100644 index 000000000..203dcffaf --- /dev/null +++ b/v4l2-apps/lib/libv4l/libv4l2/libv4l2-priv.h @@ -0,0 +1,103 @@ +/* +# (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> + +# 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 __LIBV4L2_PRIV_H +#define __LIBV4L2_PRIV_H + +#include <stdio.h> +#include <pthread.h> +#include <libv4lconvert.h> /* includes videodev2.h for us */ + +/* On 32 bits archs we always use mmap2, on 64 bits archs there is no mmap2 */ +#ifdef __NR_mmap2 +#define SYS_mmap2 __NR_mmap2 +#define MMAP2_PAGE_SHIFT 12 +#else +#define SYS_mmap2 SYS_mmap +#define MMAP2_PAGE_SHIFT 0 +#endif + +#define V4L2_MAX_DEVICES 16 +/* Warning when making this larger the frame_queued and frame_mapped members of + the v4l2_dev_info struct can no longer be a bitfield, so the code needs to + be adjusted! */ +#define V4L2_MAX_NO_FRAMES 32 +#define V4L2_DEFAULT_NREADBUFFERS 4 +#define V4L2_FRAME_BUF_SIZE (4096 * 4096) + +#define V4L2_LOG_ERR(...) \ + do { \ + if (v4l2_log_file) { \ + fprintf(v4l2_log_file, "libv4l2: error " __VA_ARGS__); \ + fflush(v4l2_log_file); \ + } else \ + fprintf(stderr, "libv4l2: error " __VA_ARGS__); \ + } while(0) + +#define V4L2_LOG_WARN(...) \ + do { \ + if (v4l2_log_file) { \ + fprintf(v4l2_log_file, "libv4l2: warning " __VA_ARGS__); \ + fflush(v4l2_log_file); \ + } else \ + fprintf(stderr, "libv4l2: warning " __VA_ARGS__); \ + } while(0) + +#define V4L2_LOG(...) \ + do { \ + if (v4l2_log_file) { \ + fprintf(v4l2_log_file, "libv4l2: " __VA_ARGS__); \ + fflush(v4l2_log_file); \ + } \ + } while(0) + +#define MIN(a,b) (((a)<(b))?(a):(b)) + +enum v4l2_io { v4l2_io_none, v4l2_io_read, v4l2_io_mmap }; + +struct v4l2_dev_info { + int fd; + int flags; + int open_count; + /* actually format of the cam */ + struct v4l2_format src_fmt; + /* fmt as seen by the application (iow after conversion) */ + struct v4l2_format dest_fmt; + pthread_mutex_t stream_lock; + unsigned int no_frames; + unsigned int nreadbuffers; + enum v4l2_io io; + struct v4lconvert_data *convert; + unsigned char *convert_mmap_buf; + /* Frame bookkeeping is only done when in read or mmap-conversion mode */ + unsigned char *frame_pointers[V4L2_MAX_NO_FRAMES]; + int frame_sizes[V4L2_MAX_NO_FRAMES]; + int frame_queued; /* 1 status bit per frame */ + /* mapping tracking of our fake (converting mmap) frame buffers, todo this + perfect we should use a map counter per frame, this is a good + approximation but there are scenarios thinkable where this doesn't work. + However no normal application not even a buggy one is likely to exhibit + the patterns needed to fail this somewhat simplified tracking */ + int frame_mapped; /* 1 status bit per frame */ + int frame_map_count; /* total number of maps of (fake) buffers combined */ +}; + +/* From log.c */ +void v4l2_log_ioctl(unsigned long int request, void *arg, int result); + +#endif diff --git a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c new file mode 100644 index 000000000..8dfcf9b71 --- /dev/null +++ b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c @@ -0,0 +1,1049 @@ +/* +# (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> + +# 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 +*/ + +/* MAKING CHANGES TO THIS FILE?? READ THIS FIRST!!! + + This file implements libv4l2, which offers v4l2_ prefixed versions of + open/close/etc. The API is 100% the same as directly opening /dev/videoX + using regular open/close/etc, the big difference is that format conversion + is done if necessary when capturing. That is if you (try to) set a capture + format which is not supported by the cam, but is supported by libv4lconvert, + then the try_fmt / set_fmt will succeed as if the cam supports the format + and on dqbuf / read the data will be converted for you and returned in + the request format. + + Important note to people making changes to this file: All functions + (v4l2_close, v4l2_ioctl, etc.) are designed to function as their regular + counterpart when they get passed a fd that is not "registered" by libv4l2, + there are 2 reasons for this: + 1) This allows us to get completely out of the way when dealing with non + capture devices. + 2) libv4l2 is the base of the v4l2convert.so wrapper lib, which is a .so + which can be LD_PRELOAD-ed and the overrules the libc's open/close/etc, + and when opening /dev/videoX calls v4l2_open. Because we behave as the + regular counterpart when the fd is not known (instead of say throwing + an error), v4l2convert.so can simply call the v4l2_ prefixed function + for all wrapped functions (except for v4l2_open which will fail when not + called on a v4l2 device). This way the wrapper does not have to keep + track of which fd's are being handled by libv4l2, as libv4l2 already + keeps track of this itself. + + This also means that libv4l2 may not use any of the regular functions + it mimics, as for example open could be a symbol in v4l2convert.so, which + in turn will call v4l2_open, so therefor v4l2_open (for example) may not + use the regular open()! + + Another important note: libv4l2 does conversion for capture usage only, if + any calls are made which are passed a v4l2_buffer or v4l2_format with a + v4l2_buf_type which is different from V4L2_BUF_TYPE_VIDEO_CAPTURE, then + the v4l2_ methods behave exactly the same as their regular counterparts. + When modifications are made, one should be carefull that this behavior is + preserved. +*/ +#include <errno.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <syscall.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include "libv4l2.h" +#include "libv4l2-priv.h" + +/* Note these flags are stored together with the flags passed to v4l2_fd_open() + in v4l2_dev_info's flags member, so care should be taken that the do not + use the same bits! */ +#define V4L2_STREAMON 0x0100 + +#define V4L2_MMAP_OFFSET_MAGIC 0xABCDEF00u + +static pthread_mutex_t v4l2_open_mutex = PTHREAD_MUTEX_INITIALIZER; +static struct v4l2_dev_info devices[V4L2_MAX_DEVICES] = { { .fd = -1 }, + { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, + { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, + { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 }}; +static int devices_used = 0; + + +static int v4l2_request_read_buffers(int index) +{ + int result; + struct v4l2_requestbuffers req; + + /* No-op if already done */ + if (devices[index].no_frames) + return 0; + + /* Request buffers */ + req.count = devices[index].nreadbuffers; + req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + req.memory = V4L2_MEMORY_MMAP; + if ((result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_REQBUFS, &req))){ + int saved_err = errno; + V4L2_LOG_ERR("requesting buffers: %s\n", strerror(errno)); + errno = saved_err; + return result; + } + + devices[index].no_frames = MIN(req.count, V4L2_MAX_NO_FRAMES); + return 0; +} + +static int v4l2_unrequest_read_buffers(int index) +{ + int result; + struct v4l2_requestbuffers req; + + /* No-op of already done */ + if (devices[index].no_frames == 0) + return 0; + + /* (Un)Request buffers */ + req.count = 0; + req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + req.memory = V4L2_MEMORY_MMAP; + if ((result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_REQBUFS, &req))) { + int saved_err = errno; + V4L2_LOG_ERR("unrequesting buffers: %s\n", strerror(errno)); + errno = saved_err; + return result; + } + + devices[index].no_frames = MIN(req.count, V4L2_MAX_NO_FRAMES); + if (devices[index].no_frames) { + V4L2_LOG_ERR("number of buffers > 0 after requesting 0 buffers\n"); + errno = EBUSY; + return -1; + } + return 0; +} + +static int v4l2_map_buffers(int index) +{ + int result = 0; + unsigned int i; + struct v4l2_buffer buf; + + for (i = 0; i < devices[index].no_frames; i++) { + if (devices[index].frame_pointers[i] != MAP_FAILED) + continue; + + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = i; + result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_QUERYBUF, &buf); + if (result) { + int saved_err = errno; + V4L2_LOG_ERR("querying buffer %u: %s\n", i, strerror(errno)); + errno = saved_err; + break; + } + + devices[index].frame_pointers[i] = (void *)syscall(SYS_mmap2, NULL, + (size_t)buf.length, PROT_READ, MAP_SHARED, devices[index].fd, + (__off_t)(buf.m.offset >> MMAP2_PAGE_SHIFT)); + if (devices[index].frame_pointers[i] == MAP_FAILED) { + int saved_err = errno; + V4L2_LOG_ERR("mmapping buffer %u: %s\n", i, strerror(errno)); + errno = saved_err; + result = -1; + break; + } + V4L2_LOG("mapped buffer %u at %p\n", i, + devices[index].frame_pointers[i]); + + devices[index].frame_sizes[i] = buf.length; + } + + return result; +} + +static void v4l2_unmap_buffers(int index) +{ + unsigned int i; + + /* unmap the buffers */ + for (i = 0; i < devices[index].no_frames; i++) { + if (devices[index].frame_pointers[i] != MAP_FAILED) { + syscall(SYS_munmap, devices[index].frame_pointers[i], + devices[index].frame_sizes[i]); + devices[index].frame_pointers[i] = MAP_FAILED; + V4L2_LOG("unmapped buffer %u\n", i); + } + } +} + +static int v4l2_streamon(int index) +{ + int result; + enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + if (!(devices[index].flags & V4L2_STREAMON)) { + if ((result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_STREAMON, + &type))) { + int saved_err = errno; + V4L2_LOG_ERR("turning on stream: %s\n", strerror(errno)); + errno = saved_err; + return result; + } + devices[index].flags |= V4L2_STREAMON; + } + + return 0; +} + +static int v4l2_streamoff(int index) +{ + int result; + enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + if (devices[index].flags & V4L2_STREAMON) { + if ((result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_STREAMOFF, + &type))) { + int saved_err = errno; + V4L2_LOG_ERR("turning off stream: %s\n", strerror(errno)); + errno = saved_err; + return result; + } + devices[index].flags &= ~V4L2_STREAMON; + + /* Stream off also unqueues all our buffers! */ + devices[index].frame_queued = 0; + } + + return 0; +} + +static int v4l2_queue_read_buffer(int index, int buffer_index) +{ + int result; + struct v4l2_buffer buf; + + if (devices[index].frame_queued & (1 << buffer_index)) + return 0; + + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = buffer_index; + if ((result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_QBUF, &buf))) { + int saved_err = errno; + V4L2_LOG_ERR("queuing buf %d: %s\n", buffer_index, strerror(errno)); + errno = saved_err; + return result; + } + + devices[index].frame_queued |= 1 << buffer_index; + return 0; +} + +static int v4l2_dequeue_read_buffer(int index, int *bytesused) +{ + int result; + struct v4l2_buffer buf; + + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + if ((result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_DQBUF, &buf))) { + int saved_err = errno; + V4L2_LOG_ERR("dequeuing buf: %s\n", strerror(errno)); + errno = saved_err; + return result; + } + + devices[index].frame_queued &= ~(1 << buf.index); + *bytesused = buf.bytesused; + return buf.index; +} + +static int v4l2_queue_read_buffers(int index) +{ + unsigned int i; + int last_error = EIO, queued = 0; + + for (i = 0; i < devices[index].no_frames; i++) { + /* Don't queue unmapped buffers (should never happen) */ + if (devices[index].frame_pointers[i] != MAP_FAILED) { + if (v4l2_queue_read_buffer(index, i)) { + last_error = errno; + continue; + } + queued++; + } + } + + if (!queued) { + errno = last_error; + return -1; + } + return 0; +} + +static int v4l2_activate_read_stream(int index) +{ + int result; + + if ((result = v4l2_request_read_buffers(index))) + return result; + + if ((result = v4l2_map_buffers(index))) + return result; + + if ((result = v4l2_queue_read_buffers(index))) + return result; + + return result = v4l2_streamon(index); +} + +static int v4l2_deactivate_read_stream(int index) +{ + int result; + + if ((result = v4l2_streamoff(index))) + return result; + + /* No need to unqueue our buffers, streamoff does that for us */ + + v4l2_unmap_buffers(index); + + if ((result = v4l2_unrequest_read_buffers(index))) + return result; + + return 0; +} + + +int v4l2_open (const char *file, int oflag, ...) +{ + int fd; + + /* original open code */ + if (oflag & O_CREAT) + { + va_list ap; + mode_t mode; + + va_start (ap, oflag); + mode = va_arg (ap, mode_t); + + fd = syscall(SYS_open, file, oflag, mode); + + va_end(ap); + } + else + fd = syscall(SYS_open, file, oflag); + /* end of original open code */ + + if (fd == -1) + return fd; + + if (v4l2_fd_open(fd, 0) == -1) { + int saved_err = errno; + syscall(SYS_close, fd); + errno = saved_err; + return -1; + } + + return fd; +} + +int v4l2_fd_open(int fd, int v4l2_flags) +{ + int i, index; + char *lfname; + struct v4l2_capability cap; + struct v4l2_format fmt; + struct v4lconvert_data *convert; + + /* If no log file was set by the app, see if one was specified through the + environment */ + if (!v4l2_log_file && (lfname = getenv("LIBV4L2_LOG_FILENAME"))) + v4l2_log_file = fopen(lfname, "w"); + + /* check that this is an v4l2 device */ + if (syscall(SYS_ioctl, fd, VIDIOC_QUERYCAP, &cap)) { + int saved_err = errno; + V4L2_LOG_ERR("getting capabilities: %s\n", strerror(errno)); + errno = saved_err; + return -1; + } + + /* we only add functionality for video capture devices */ + if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) + return fd; + + /* Get current cam format */ + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (syscall(SYS_ioctl, fd, VIDIOC_G_FMT, &fmt)) { + int saved_err = errno; + V4L2_LOG_ERR("getting pixformat: %s\n", strerror(errno)); + errno = saved_err; + return -1; + } + + /* init libv4lconvert */ + if (!(convert = v4lconvert_create(fd))) + return -1; + + /* So we have a v4l2 capture device, register it in our devices array */ + pthread_mutex_lock(&v4l2_open_mutex); + for (index = 0; index < V4L2_MAX_DEVICES; index++) + if(devices[index].fd == -1) { + devices[index].fd = fd; + break; + } + pthread_mutex_unlock(&v4l2_open_mutex); + + if (index == V4L2_MAX_DEVICES) { + V4L2_LOG_ERR("attempting to open more then %d video devices\n", + V4L2_MAX_DEVICES); + errno = EBUSY; + return -1; + } + + devices[index].flags = v4l2_flags; + devices[index].open_count = 1; + devices[index].src_fmt = fmt; + devices[index].dest_fmt = fmt; + + pthread_mutex_init(&devices[index].stream_lock, NULL); + + devices[index].no_frames = 0; + devices[index].nreadbuffers = V4L2_DEFAULT_NREADBUFFERS; + devices[index].io = v4l2_io_none; + devices[index].convert = convert; + devices[index].convert_mmap_buf = MAP_FAILED; + for (i = 0; i < V4L2_MAX_NO_FRAMES; i++) { + devices[index].frame_pointers[i] = MAP_FAILED; + } + devices[index].frame_queued = 0; + devices[index].frame_mapped = 0; + devices[index].frame_map_count = 0; + + if (index >= devices_used) + devices_used = index + 1; + + V4L2_LOG("open: %d\n", fd); + + return fd; +} + +/* Is this an fd for which we are emulating v4l1 ? */ +static int v4l2_get_index(int fd) +{ + int index; + + /* We never handle fd -1 */ + if (fd == -1) + return -1; + + for (index = 0; index < devices_used; index++) + if (devices[index].fd == fd) + break; + + if (index == devices_used) + return -1; + + return index; +} + + +int v4l2_close(int fd) +{ + int index, result; + + if ((index = v4l2_get_index(fd)) == -1) + return syscall(SYS_close, fd); + + /* Abuse stream_lock to stop 2 closes from racing and trying to free the + resources twice */ + pthread_mutex_lock(&devices[index].stream_lock); + devices[index].open_count--; + result = devices[index].open_count != 0; + pthread_mutex_unlock(&devices[index].stream_lock); + + if (result) + return 0; + + /* Free resources */ + v4l2_unmap_buffers(index); + v4lconvert_destroy(devices[index].convert); + if (devices[index].convert_mmap_buf != MAP_FAILED) { + if (devices[index].frame_mapped || devices[index].frame_map_count) + V4L2_LOG( + "v4l2 mmap buffers still mapped on close(), mask: %08x, count: %d\n", + (unsigned int)devices[index].frame_mapped, + devices[index].frame_map_count); + else + syscall(SYS_munmap, devices[index].convert_mmap_buf, + devices[index].no_frames * V4L2_FRAME_BUF_SIZE); + devices[index].convert_mmap_buf = MAP_FAILED; + } + + /* Remove the fd from our list of managed fds before closing it, because as + soon as we've done the actual close the fd maybe returned by an open in + another thread and we don't want to intercept calls to this new fd. */ + devices[index].fd = -1; + + /* Since we've marked the fd as no longer used, and freed the resources, + redo the close in case it was interrupted */ + do { + result = syscall(SYS_close, fd); + } while (result == -1 && errno == EINTR); + + V4L2_LOG("close: %d\n", fd); + + return result; +} + +int v4l2_dup(int fd) +{ + int index; + + if ((index = v4l2_get_index(fd)) == -1) + return syscall(SYS_dup, fd); + + devices[index].open_count++; + + return fd; +} + + +int v4l2_ioctl (int fd, unsigned long int request, ...) +{ + void *arg; + va_list ap; + int result, converting, index, saved_err; + int is_capture_request = 0, stream_needs_locking = 0; + + va_start (ap, request); + arg = va_arg (ap, void *); + va_end (ap); + + if ((index = v4l2_get_index(fd)) == -1) + return syscall(SYS_ioctl, fd, request, arg); + + /* Appearantly the kernel and / or glibc ignore the 32 most significant bits + when long = 64 bits, and some applications pass an int holding the req to + ioctl, causing it to get sign extended, depending upon this behavior */ + request = (unsigned int)request; + + /* Is this a capture request and do we need to take the stream lock? */ + switch (request) { + case VIDIOC_ENUM_FMT: + if (((struct v4l2_fmtdesc *)arg)->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + is_capture_request = 1; + break; + case VIDIOC_TRY_FMT: + if (((struct v4l2_format *)arg)->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + is_capture_request = 1; + break; + case VIDIOC_S_FMT: + case VIDIOC_G_FMT: + if (((struct v4l2_format *)arg)->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { + is_capture_request = 1; + stream_needs_locking = 1; + } + break; + case VIDIOC_REQBUFS: + if (((struct v4l2_requestbuffers *)arg)->type == + V4L2_BUF_TYPE_VIDEO_CAPTURE) { + is_capture_request = 1; + stream_needs_locking = 1; + } + break; + case VIDIOC_QUERYBUF: + case VIDIOC_QBUF: + case VIDIOC_DQBUF: + if (((struct v4l2_buffer *)arg)->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { + is_capture_request = 1; + stream_needs_locking = 1; + } + break; + case VIDIOC_STREAMON: + case VIDIOC_STREAMOFF: + if (*((enum v4l2_buf_type *)arg) == V4L2_BUF_TYPE_VIDEO_CAPTURE) { + is_capture_request = 1; + stream_needs_locking = 1; + } + } + + if (!is_capture_request) { + result = syscall(SYS_ioctl, fd, request, arg); + saved_err = errno; + v4l2_log_ioctl(request, arg, result); + errno = saved_err; + return result; + } + + + if (stream_needs_locking) + pthread_mutex_lock(&devices[index].stream_lock); + + converting = devices[index].src_fmt.fmt.pix.pixelformat != + devices[index].dest_fmt.fmt.pix.pixelformat; + + + switch (request) { + case VIDIOC_ENUM_FMT: + result = v4lconvert_enum_fmt(devices[index].convert, arg); + break; + + case VIDIOC_TRY_FMT: + result = v4lconvert_try_format(devices[index].convert, arg, NULL); + break; + + case VIDIOC_S_FMT: + { + struct v4l2_format src_fmt, *dest_fmt = arg; + + if (!memcmp(&devices[index].dest_fmt, dest_fmt, sizeof(*dest_fmt))) { + result = 0; + break; + } + + /* Don't allow changing the format when mmap-ed IO is active, we could + allow this to happen in certain special circumstances, but it is + best to consistently deny this so that application developers do not + go expect this to work, because in their test setup it happens to + work. This also keeps the code much saner. */ + if (devices[index].io == v4l2_io_mmap) { + errno = EBUSY; + result = -1; + break; + } + + if (devices[index].flags & V4L2_DISABLE_CONVERSION) { + result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_TRY_FMT, + dest_fmt); + src_fmt = *dest_fmt; + } else { + result = v4lconvert_try_format(devices[index].convert, dest_fmt, + &src_fmt); + } + + if (result) + break; + + /* Maybe after try format has adjusted width/height etc, to whats + available nothing has changed (on the cam side) ? */ + if (!memcmp(&devices[index].src_fmt, &src_fmt, sizeof(src_fmt))) { + devices[index].dest_fmt = *dest_fmt; + result = 0; + break; + } + + if (devices[index].io == v4l2_io_read) { + V4L2_LOG("deactivating read-stream for format change\n"); + if ((result = v4l2_deactivate_read_stream(index))) { + /* Undo what we've done to leave things in a consisten state */ + if (v4l2_activate_read_stream(index)) + V4L2_LOG_ERR( + "reactivating stream after deactivate failure (AAIIEEEE)\n"); + break; + } + } + + result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_S_FMT, &src_fmt); + if (result) { + saved_err = errno; + V4L2_LOG_ERR("setting pixformat: %s\n", strerror(errno)); + /* Report to the app dest_fmt has not changed */ + *dest_fmt = devices[index].dest_fmt; + errno = saved_err; + break; + } + + devices[index].src_fmt = src_fmt; + devices[index].dest_fmt = *dest_fmt; + } + break; + + case VIDIOC_G_FMT: + { + struct v4l2_format* fmt = arg; + + *fmt = devices[index].dest_fmt; + result = 0; + } + break; + + case VIDIOC_REQBUFS: + { + struct v4l2_requestbuffers *req = arg; + + /* Don't allow mixing read / mmap io, either we control the buffers + (read based io), or the app does */ + if (devices[index].io == v4l2_io_read) { + V4L2_LOG_ERR("to change from read io to mmap io open and close the device first!\n"); + errno = EBUSY; + result = -1; + break; + } + + /* Are any of our fake (convert_mmap_buf) buffers still mapped ? */ + if (devices[index].frame_mapped || devices[index].frame_map_count) { + errno = EBUSY; + result = -1; + break; + } + + /* IMPROVEME (maybe?) add support for userptr's? */ + if (req->memory != V4L2_MEMORY_MMAP) { + errno = EINVAL; + result = -1; + break; + } + + /* No more buffers then we can manage please */ + if (req->count > V4L2_MAX_NO_FRAMES) + req->count = V4L2_MAX_NO_FRAMES; + + /* Stop stream and unmap our real mapping of the buffers + (only relevant when we're converting, otherwise a no-op) */ + v4l2_streamoff(index); + v4l2_unmap_buffers(index); + + result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_REQBUFS, req); + if (result) + break; + + /* If we got more frames then we can handle lie to the app */ + if (req->count > V4L2_MAX_NO_FRAMES) + req->count = V4L2_MAX_NO_FRAMES; + + /* Force reallocation of convert_mmap_buf to fit the new no_frames */ + syscall(SYS_munmap, devices[index].convert_mmap_buf, + devices[index].no_frames * V4L2_FRAME_BUF_SIZE); + devices[index].convert_mmap_buf = MAP_FAILED; + devices[index].no_frames = req->count; + devices[index].io = req->count? v4l2_io_mmap:v4l2_io_none; + } + break; + + case VIDIOC_QUERYBUF: + { + struct v4l2_buffer *buf = arg; + + /* Do a real query even when converting to let the driver fill in + things like buf->field */ + result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_QUERYBUF, buf); + if (result || !converting) + break; + + buf->m.offset = V4L2_MMAP_OFFSET_MAGIC | buf->index; + buf->length = V4L2_FRAME_BUF_SIZE; + } + break; + + case VIDIOC_QBUF: + result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_QBUF, arg); + break; + + case VIDIOC_DQBUF: + { + struct v4l2_buffer *buf = arg; + + result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_DQBUF, buf); + if (result) { + V4L2_LOG_ERR("dequeing buffer: %s\n", strerror(errno)); + break; + } + + if (!converting) + break; + + /* An application can do a DQBUF before mmap-ing in the buffer, + but we need the buffer _now_ to write our converted data + to it! */ + if (devices[index].convert_mmap_buf == MAP_FAILED) { + devices[index].convert_mmap_buf = (void *)syscall(SYS_mmap2, + (size_t)( + devices[index].no_frames * + V4L2_FRAME_BUF_SIZE), + PROT_READ|PROT_WRITE, + MAP_ANONYMOUS|MAP_PRIVATE, + -1, 0); + if (devices[index].convert_mmap_buf == MAP_FAILED) { + saved_err = errno; + V4L2_LOG_ERR("allocating conversion buffer\n"); + errno = saved_err; + result = -1; + break; + } + } + + /* Make sure we have the real v4l2 buffers mapped before trying to + read from them */ + if ((result = v4l2_map_buffers(index))) + break; + + result = v4lconvert_convert(devices[index].convert, + &devices[index].src_fmt, &devices[index].dest_fmt, + devices[index].frame_pointers[buf->index], + buf->bytesused, + devices[index].convert_mmap_buf + + buf->index * V4L2_FRAME_BUF_SIZE, + V4L2_FRAME_BUF_SIZE); + if (result < 0) { + V4L2_LOG_ERR("converting / decoding frame data: %s\n", + v4lconvert_get_error_message(devices[index].convert)); + break; + } + + buf->bytesused = result; + buf->length = V4L2_FRAME_BUF_SIZE; + + result = 0; + } + break; + + case VIDIOC_STREAMON: + case VIDIOC_STREAMOFF: + if (devices[index].io != v4l2_io_mmap) { + errno = EINVAL; + result = -1; + break; + } + + if (request == VIDIOC_STREAMON) + result = v4l2_streamon(index); + else + result = v4l2_streamoff(index); + break; + + default: + result = syscall(SYS_ioctl, fd, request, arg); + } + + if (stream_needs_locking) + pthread_mutex_unlock(&devices[index].stream_lock); + + saved_err = errno; + v4l2_log_ioctl(request, arg, result); + errno = saved_err; + + return result; +} + + +ssize_t v4l2_read (int fd, void* buffer, size_t n) +{ + ssize_t result; + int index, bytesused = 0, frame_index; + + if ((index = v4l2_get_index(fd)) == -1) + return syscall(SYS_read, fd, buffer, n); + + pthread_mutex_lock(&devices[index].stream_lock); + + if (devices[index].io == v4l2_io_mmap) { + V4L2_LOG_ERR("to change from mmap io to read io first do request_buffers with a count of 0\n"); + errno = EBUSY; + result = -1; + goto leave; + } + devices[index].io = v4l2_io_read; + + if ((result = v4l2_activate_read_stream(index))) + goto leave; + + if ((frame_index = v4l2_dequeue_read_buffer(index, &bytesused)) < 0) { + result = -1; + goto leave; + } + + result = v4lconvert_convert(devices[index].convert, + &devices[index].src_fmt, &devices[index].dest_fmt, + devices[index].frame_pointers[frame_index], bytesused, + buffer, n); + + v4l2_queue_read_buffer(index, frame_index); + + if (result < 0) + V4L2_LOG_ERR("converting / decoding frame data: %s\n", + v4lconvert_get_error_message(devices[index].convert)); + +leave: + pthread_mutex_unlock(&devices[index].stream_lock); + + return result; +} + +void *v4l2_mmap(void *start, size_t length, int prot, int flags, int fd, + __off64_t offset) +{ + int index; + unsigned int buffer_index; + void *result; + + if ((index = v4l2_get_index(fd)) == -1 || + /* Check if the mmap data matches our answer to QUERY_BUF, if it doesn't + let the kernel handle it (to allow for mmap based non capture use) */ + start || length != V4L2_FRAME_BUF_SIZE || + ((unsigned int)offset & ~0xFFu) != V4L2_MMAP_OFFSET_MAGIC) { + if (index != -1) + V4L2_LOG("Passing mmap(%p, %d, ..., %x, through to the driver\n", + start, (int)length, (int)offset); + + if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1)) { + errno = EINVAL; + return MAP_FAILED; + } + + return (void *)syscall(SYS_mmap2, start, length, prot, flags, fd, + (__off_t)(offset >> MMAP2_PAGE_SHIFT)); + } + + pthread_mutex_lock(&devices[index].stream_lock); + + buffer_index = offset & 0xff; + if (buffer_index >= devices[index].no_frames || + devices[index].io != v4l2_io_mmap || + /* Got magic offset and not converting ?? */ + devices[index].src_fmt.fmt.pix.pixelformat == + devices[index].dest_fmt.fmt.pix.pixelformat) { + errno = EINVAL; + result = MAP_FAILED; + goto leave; + } + + if (devices[index].convert_mmap_buf == MAP_FAILED) { + devices[index].convert_mmap_buf = (void *)syscall(SYS_mmap2, NULL, + (size_t)( + devices[index].no_frames * + V4L2_FRAME_BUF_SIZE), + PROT_READ|PROT_WRITE, + MAP_ANONYMOUS|MAP_PRIVATE, + -1, 0); + if (devices[index].convert_mmap_buf == MAP_FAILED) { + int saved_err = errno; + V4L2_LOG_ERR("allocating conversion buffer\n"); + errno = saved_err; + result = MAP_FAILED; + goto leave; + } + } + + devices[index].frame_mapped |= 1 << buffer_index; + devices[index].frame_map_count++; + + result = devices[index].convert_mmap_buf + + buffer_index * V4L2_FRAME_BUF_SIZE; + + V4L2_LOG("Fake (conversion) mmap buf %u, seen by app at: %p\n", + buffer_index, result); + +leave: + pthread_mutex_unlock(&devices[index].stream_lock); + + return result; +} + +int v4l2_munmap(void *_start, size_t length) +{ + int index; + unsigned int buffer_index; + unsigned char *start = _start; + + /* Is this memory ours? */ + if (start != MAP_FAILED && length == V4L2_FRAME_BUF_SIZE) { + for (index = 0; index < devices_used; index++) + if (devices[index].fd != -1 && + devices[index].convert_mmap_buf != MAP_FAILED && + start >= devices[index].convert_mmap_buf && + (start - devices[index].convert_mmap_buf) % length == 0) + break; + + if (index != devices_used) { + int unmapped = 0; + + pthread_mutex_lock(&devices[index].stream_lock); + + buffer_index = (start - devices[index].convert_mmap_buf) / length; + + /* Redo our checks now that we have the lock, things may have changed */ + if (devices[index].convert_mmap_buf != MAP_FAILED && + start >= devices[index].convert_mmap_buf && + (start - devices[index].convert_mmap_buf) % length == 0 && + buffer_index < devices[index].no_frames) { + devices[index].frame_mapped &= ~(1 << buffer_index); + if (devices[index].frame_map_count > 0) + devices[index].frame_map_count--; + unmapped = 1; + } + + pthread_mutex_unlock(&devices[index].stream_lock); + + if (unmapped) { + V4L2_LOG("v4l2 fake buffer munmap %p, %d\n", start, (int)length); + return 0; + } + } + } + + V4L2_LOG("v4l2 unknown munmap %p, %d\n", start, (int)length); + + return syscall(SYS_munmap, _start, length); +} + +/* Misc utility functions */ +int v4l2_set_control(int fd, int cid, int value) +{ + struct v4l2_queryctrl qctrl = { .id = cid }; + struct v4l2_control ctrl = { .id = cid }; + int result; + + if ((result = syscall(SYS_ioctl, fd, VIDIOC_QUERYCTRL, &qctrl))) + return result; + + if (!(qctrl.flags & V4L2_CTRL_FLAG_DISABLED) && + !(qctrl.flags & V4L2_CTRL_FLAG_GRABBED)) { + if (qctrl.type == V4L2_CTRL_TYPE_BOOLEAN) + ctrl.value = value? 1:0; + else + ctrl.value = (value * (qctrl.maximum - qctrl.minimum) + 32767) / 65535 + + qctrl.minimum; + + result = syscall(SYS_ioctl, fd, VIDIOC_S_CTRL, &ctrl); + } + + return result; +} + +int v4l2_get_control(int fd, int cid) +{ + struct v4l2_queryctrl qctrl = { .id = cid }; + struct v4l2_control ctrl = { .id = cid }; + + if (syscall(SYS_ioctl, fd, VIDIOC_QUERYCTRL, &qctrl)) + return 0; + + if (qctrl.flags & V4L2_CTRL_FLAG_DISABLED) + return 0; + + if (syscall(SYS_ioctl, fd, VIDIOC_G_CTRL, &ctrl)) + return 0; + + return ((ctrl.value - qctrl.minimum) * 65535 + + (qctrl.maximum - qctrl.minimum) / 2) / + (qctrl.maximum - qctrl.minimum); +} diff --git a/v4l2-apps/lib/libv4l/libv4l2/log.c b/v4l2-apps/lib/libv4l/libv4l2/log.c new file mode 100644 index 000000000..982a185c6 --- /dev/null +++ b/v4l2-apps/lib/libv4l/libv4l2/log.c @@ -0,0 +1,138 @@ +/* +# (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> + +# 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 +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <linux/ioctl.h> +/* These headers are not needed by us, but by linux/videodev2.h, + which is broken on some systems and doesn't include them itself :( */ +#include <sys/time.h> +#include <asm/types.h> +/* end broken header workaround includes */ +#include <linux/videodev2.h> + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) + +FILE *v4l2_log_file = NULL; + +static const char *v4l2_ioctls[] = { + /* start v4l2 ioctls */ + [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP", + [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED", + [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT", + [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT", + [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT", + [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS", + [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF", + [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF", + [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF", + [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY", + [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF", + [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF", + [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON", + [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF", + [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM", + [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM", + [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD", + [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD", + [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD", + [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT", + [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL", + [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL", + [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER", + [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER", + [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO", + [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO", + [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL", + [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU", + [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT", + [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT", + [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT", + [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT", + [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT", + [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT", + [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT", + [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR", + [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR", + [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY", + [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY", + [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP", + [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP", + [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP", + [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP", + [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP", + [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD", + [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT", + [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO", + [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT", + [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY", + [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY", + [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP", + [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS", + [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS", + [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS", + [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS", +}; + +void v4l2_log_ioctl(unsigned long int request, void *arg, int result) +{ + const char *ioctl_str; + char buf[40]; + + if (!v4l2_log_file) + return; + + if (_IOC_TYPE(request) == 'V' && _IOC_NR(request) < ARRAY_SIZE(v4l2_ioctls)) + ioctl_str = v4l2_ioctls[_IOC_NR(request)]; + else { + snprintf(buf, sizeof(buf), "unknown request: %c %d\n", + (int)_IOC_TYPE(request), (int)_IOC_NR(request)); + ioctl_str = buf; + } + + fprintf(v4l2_log_file, "request == %s\n", ioctl_str); + + switch (request) { + case VIDIOC_G_FMT: + case VIDIOC_S_FMT: + case VIDIOC_TRY_FMT: + { + struct v4l2_format* fmt = arg; + int pixfmt = fmt->fmt.pix.pixelformat; + + if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { + fprintf(v4l2_log_file, " pixelformat: %c%c%c%c %dx%d\n", + pixfmt & 0xff, + (pixfmt >> 8) & 0xff, + (pixfmt >> 16) & 0xff, + pixfmt >> 24, + fmt->fmt.pix.width, + fmt->fmt.pix.height); + fprintf(v4l2_log_file, " field: %d bytesperline: %d imagesize%d\n", + (int)fmt->fmt.pix.field, (int)fmt->fmt.pix.bytesperline, + (int)fmt->fmt.pix.sizeimage); + fprintf(v4l2_log_file, " colorspace: %d, priv: %x\n", + (int)fmt->fmt.pix.colorspace, (int)fmt->fmt.pix.priv); + } + } + break; + } + + fprintf(v4l2_log_file, "result == %d\n", result); + fflush(v4l2_log_file); +} diff --git a/v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c b/v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c new file mode 100644 index 000000000..7db1ca6d6 --- /dev/null +++ b/v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c @@ -0,0 +1,152 @@ +/* +# open/close/ioctl/mmap/munmap library call wrapper doing format conversion +# for v4l2 applications which want to be able to simply capture bgr24 / yuv420 +# from v4l2 devices with more exotic frame formats. + +# (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> + +# 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 +*/ + +#define _LARGEFILE64_SOURCE 1 + +#include <stdarg.h> +#include <stdlib.h> +#include <syscall.h> +#include <fcntl.h> +#include <string.h> +/* These headers are not needed by us, but by linux/videodev2.h, + which is broken on some systems and doesn't include them itself :( */ +#include <sys/time.h> +#include <asm/types.h> +#include <linux/ioctl.h> +/* end broken header workaround includes */ +#include <linux/videodev2.h> +#include <libv4l2.h> + +/* Check that open/read/mmap is not a define */ +#if defined open || defined read || defined mmap +#error open/read/mmap is a prepocessor macro !! +#endif + +int open (const char *file, int oflag, ...) +{ + int fd; + struct v4l2_capability cap; + + /* original open code */ + if (oflag & O_CREAT) + { + va_list ap; + mode_t mode; + + va_start (ap, oflag); + mode = va_arg (ap, mode_t); + + fd = syscall(SYS_open, file, oflag, mode); + + va_end(ap); + } else + fd = syscall(SYS_open, file, oflag); + /* end of original open code */ + + if (fd == -1) + return fd; + + /* check if we're opening a video4linux2 device */ + if (strncmp(file, "/dev/video", 10)) + return fd; + + /* check that this is an v4l2 device, libv4l2 only supports v4l2 devices */ + if (syscall(SYS_ioctl, fd, VIDIOC_QUERYCAP, &cap)) + return fd; + + /* libv4l2 only adds functionality to capture capable devices */ + if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) + return fd; + + /* Try to Register with libv4l2 (in case of failure pass the fd to the + application as is) */ + v4l2_fd_open(fd, V4L2_ENABLE_ENUM_FMT_EMULATION); + + return fd; +} + +int open64(const char *file, int oflag, ...) +{ + int fd; + + /* original open code */ + if (oflag & O_CREAT) + { + va_list ap; + mode_t mode; + + va_start (ap, oflag); + mode = va_arg (ap, mode_t); + + fd = open(file, oflag | O_LARGEFILE, mode); + + va_end(ap); + } else + fd = open(file, oflag | O_LARGEFILE); + /* end of original open code */ + + return fd; +} + +int close(int fd) +{ + return v4l2_close(fd); +} + +int dup(int fd) +{ + return v4l2_dup(fd); +} + +int ioctl (int fd, unsigned long int request, ...) +{ + void *arg; + va_list ap; + + va_start (ap, request); + arg = va_arg (ap, void *); + va_end (ap); + + return v4l2_ioctl (fd, request, arg); +} + +ssize_t read (int fd, void* buffer, size_t n) +{ + return v4l2_read (fd, buffer, n); +} + +void mmap(void *start, size_t length, int prot, int flags, int fd, + __off_t offset) +{ + return v4l2_mmap(start, length, prot, flags, fd, offset); +} + +void mmap64(void *start, size_t length, int prot, int flags, int fd, + __off64_t offset) +{ + return v4l2_mmap(start, length, prot, flags, fd, offset); +} + +int munmap(void *start, size_t length) +{ + return v4l2_munmap(start, length); +} diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/Makefile b/v4l2-apps/lib/libv4l/libv4lconvert/Makefile new file mode 100644 index 000000000..38071de94 --- /dev/null +++ b/v4l2-apps/lib/libv4l/libv4lconvert/Makefile @@ -0,0 +1,50 @@ +CC = gcc +LD = gcc + +CPPFLAGS = -fPIC -I../include -I../../../../linux/include + +CFLAGS := -g -O1 +CFLAGS += -Wall -W -Wno-unused -Wpointer-arith -Wstrict-prototypes + +LDFLAGS = -shared + +CONVERT_LIB = libv4lconvert.so +CONVERT_OBJS = libv4lconvert.o tinyjpeg.o sn9c10x.o pac207.o \ + jidctflt.o spca561-decompress.o rgbyuv.o spca501.o bayer.o +TARGETS = $(CONVERT_LIB) +INCLUDES = ../include/libv4lconvert.h + +ifeq ($(LIB_RELEASE),) +LIB_RELEASE = 0 +endif + +ifeq ($(PREFIX),) +PREFIX = /usr/local +endif + +ifeq ($(LIBDIR),) +LIBDIR = $(PREFIX)/lib +endif + +all: $(TARGETS) + +$(CONVERT_LIB): $(CONVERT_OBJS) + +install: all + mkdir -p $(DESTDIR)$(PREFIX)/include + install -p -m 644 $(INCLUDES) $(DESTDIR)$(PREFIX)/include + mkdir -p $(DESTDIR)$(LIBDIR) + install -m 755 $(CONVERT_LIB).$(LIB_RELEASE) $(DESTDIR)$(LIBDIR) + cd $(DESTDIR)$(LIBDIR) && \ + ln -f -s $(CONVERT_LIB).$(LIB_RELEASE) $(CONVERT_LIB) + +clean:: + rm -f *.so* *.o log *~ + rm -f *.d + +%.o: %.c + $(CC) -c -MMD $(CPPFLAGS) $(CFLAGS) -o $@ $< + +%.so: + $(CC) $(LDFLAGS) -Wl,-soname,$@.$(LIB_RELEASE) -o $@.$(LIB_RELEASE) $^ + ln -f -s $@.$(LIB_RELEASE) $@ diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/bayer.c b/v4l2-apps/lib/libv4l/libv4lconvert/bayer.c new file mode 100644 index 000000000..166c13011 --- /dev/null +++ b/v4l2-apps/lib/libv4l/libv4lconvert/bayer.c @@ -0,0 +1,597 @@ +/* + * lib4lconvert, video4linux2 format conversion lib + * (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> + * + * This library 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 library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Note: original bayer_to_bgr24 code from : + * 1394-Based Digital Camera Control Library + * + * Bayer pattern decoding functions + * + * Written by Damien Douxchamps and Frederic Devernay + * + * Note that the original bayer.c in libdc1394 supports many different + * bayer decode algorithms, for lib4lconvert the one in this file has been + * chosen (and optimized a bit) and the other algorithm's have been removed, + * see bayer.c from libdc1394 for all supported algorithms + */ + +#include <string.h> +#include "libv4lconvert-priv.h" + +/************************************************************** + * Color conversion functions for cameras that can * + * output raw-Bayer pattern images, such as some Basler and * + * Point Grey camera. Most of the algos presented here come * + * from http://www-ise.stanford.edu/~tingchen/ and have been * + * converted from Matlab to C and extended to all elementary * + * patterns. * + **************************************************************/ + +/* insprired by OpenCV's Bayer decoding */ +static void v4lconvert_border_bayer_line_to_bgr24( + const unsigned char* bayer, const unsigned char* adjacent_bayer, + unsigned char *bgr, int width, int start_with_green, int blue_line) +{ + int t0, t1; + + if (start_with_green) { + /* First pixel */ + if (blue_line) { + *bgr++ = bayer[1]; + *bgr++ = bayer[0]; + *bgr++ = adjacent_bayer[0]; + } else { + *bgr++ = adjacent_bayer[0]; + *bgr++ = bayer[0]; + *bgr++ = bayer[1]; + } + /* Second pixel */ + t0 = (bayer[0] + bayer[2] + adjacent_bayer[1] + 1) / 3; + t1 = (adjacent_bayer[0] + adjacent_bayer[2] + 1) >> 1; + if (blue_line) { + *bgr++ = bayer[1]; + *bgr++ = t0; + *bgr++ = t1; + } else { + *bgr++ = t1; + *bgr++ = t0; + *bgr++ = bayer[1]; + } + bayer++; + adjacent_bayer++; + width -= 2; + } else { + /* First pixel */ + t0 = (bayer[1] + adjacent_bayer[0] + 1) >> 1; + if (blue_line) { + *bgr++ = bayer[0]; + *bgr++ = t0; + *bgr++ = adjacent_bayer[1]; + } else { + *bgr++ = adjacent_bayer[1]; + *bgr++ = t0; + *bgr++ = bayer[0]; + } + width--; + } + + if (blue_line) { + for ( ; width > 2; width -= 2) { + t0 = (bayer[0] + bayer[2] + 1) >> 1; + *bgr++ = t0; + *bgr++ = bayer[1]; + *bgr++ = adjacent_bayer[1]; + bayer++; + adjacent_bayer++; + + t0 = (bayer[0] + bayer[2] + adjacent_bayer[1] + 1) / 3; + t1 = (adjacent_bayer[0] + adjacent_bayer[2] + 1) >> 1; + *bgr++ = bayer[1]; + *bgr++ = t0; + *bgr++ = t1; + bayer++; + adjacent_bayer++; + } + } else { + for ( ; width > 2; width -= 2) { + t0 = (bayer[0] + bayer[2] + 1) >> 1; + *bgr++ = adjacent_bayer[1]; + *bgr++ = bayer[1]; + *bgr++ = t0; + bayer++; + adjacent_bayer++; + + t0 = (bayer[0] + bayer[2] + adjacent_bayer[1] + 1) / 3; + t1 = (adjacent_bayer[0] + adjacent_bayer[2] + 1) >> 1; + *bgr++ = t1; + *bgr++ = t0; + *bgr++ = bayer[1]; + bayer++; + adjacent_bayer++; + } + } + + if (width == 2) { + /* Second to last pixel */ + t0 = (bayer[0] + bayer[2] + 1) >> 1; + if (blue_line) { + *bgr++ = t0; + *bgr++ = bayer[1]; + *bgr++ = adjacent_bayer[1]; + } else { + *bgr++ = adjacent_bayer[1]; + *bgr++ = bayer[1]; + *bgr++ = t0; + } + /* Last pixel */ + t0 = (bayer[1] + adjacent_bayer[2] + 1) >> 1; + if (blue_line) { + *bgr++ = bayer[2]; + *bgr++ = t0; + *bgr++ = adjacent_bayer[1]; + } else { + *bgr++ = adjacent_bayer[1]; + *bgr++ = t0; + *bgr++ = bayer[2]; + } + } else { + /* Last pixel */ + if (blue_line) { + *bgr++ = bayer[0]; + *bgr++ = bayer[1]; + *bgr++ = adjacent_bayer[1]; + } else { + *bgr++ = adjacent_bayer[1]; + *bgr++ = bayer[1]; + *bgr++ = bayer[0]; + } + } +} + +/* From libdc1394, which on turn was based on OpenCV's Bayer decoding */ +void v4lconvert_bayer_to_bgr24(const unsigned char *bayer, + unsigned char *bgr, int width, int height, unsigned int pixfmt) +{ + int blue_line = pixfmt == V4L2_PIX_FMT_SBGGR8 + || pixfmt == V4L2_PIX_FMT_SGBRG8; + int start_with_green = pixfmt == V4L2_PIX_FMT_SGBRG8 + || pixfmt == V4L2_PIX_FMT_SGRBG8; + + /* render the first line */ + v4lconvert_border_bayer_line_to_bgr24(bayer, bayer + width, bgr, width, + start_with_green, blue_line); + bgr += width * 3; + + /* reduce height by 2 because of the special case top/bottom line */ + for (height -= 2; height; height--) { + int t0, t1; + /* (width - 2) because of the border */ + const unsigned char *bayerEnd = bayer + (width - 2); + + if (start_with_green) { + /* OpenCV has a bug in the next line, which was + t0 = (bayer[0] + bayer[width * 2] + 1) >> 1; */ + t0 = (bayer[1] + bayer[width * 2 + 1] + 1) >> 1; + /* Write first pixel */ + t1 = (bayer[0] + bayer[width * 2] + bayer[width + 1] + 1) / 3; + if (blue_line) { + *bgr++ = t0; + *bgr++ = t1; + *bgr++ = bayer[width]; + } else { + *bgr++ = bayer[width]; + *bgr++ = t1; + *bgr++ = t0; + } + + /* Write second pixel */ + t1 = (bayer[width] + bayer[width + 2] + 1) >> 1; + if (blue_line) { + *bgr++ = t0; + *bgr++ = bayer[width + 1]; + *bgr++ = t1; + } else { + *bgr++ = t1; + *bgr++ = bayer[width + 1]; + *bgr++ = t0; + } + bayer++; + } else { + /* Write first pixel */ + t0 = (bayer[0] + bayer[width * 2] + 1) >> 1; + if (blue_line) { + *bgr++ = t0; + *bgr++ = bayer[width]; + *bgr++ = bayer[width + 1]; + } else { + *bgr++ = bayer[width + 1]; + *bgr++ = bayer[width]; + *bgr++ = t0; + } + } + + if (blue_line) { + for (; bayer <= bayerEnd - 2; bayer += 2) { + t0 = (bayer[0] + bayer[2] + bayer[width * 2] + + bayer[width * 2 + 2] + 2) >> 2; + t1 = (bayer[1] + bayer[width] + + bayer[width + 2] + bayer[width * 2 + 1] + + 2) >> 2; + *bgr++ = t0; + *bgr++ = t1; + *bgr++ = bayer[width + 1]; + + t0 = (bayer[2] + bayer[width * 2 + 2] + 1) >> 1; + t1 = (bayer[width + 1] + bayer[width + 3] + + 1) >> 1; + *bgr++ = t0; + *bgr++ = bayer[width + 2]; + *bgr++ = t1; + } + } else { + for (; bayer <= bayerEnd - 2; bayer += 2) { + t0 = (bayer[0] + bayer[2] + bayer[width * 2] + + bayer[width * 2 + 2] + 2) >> 2; + t1 = (bayer[1] + bayer[width] + + bayer[width + 2] + bayer[width * 2 + 1] + + 2) >> 2; + *bgr++ = bayer[width + 1]; + *bgr++ = t1; + *bgr++ = t0; + + t0 = (bayer[2] + bayer[width * 2 + 2] + 1) >> 1; + t1 = (bayer[width + 1] + bayer[width + 3] + + 1) >> 1; + *bgr++ = t1; + *bgr++ = bayer[width + 2]; + *bgr++ = t0; + } + } + + if (bayer < bayerEnd) { + /* write second to last pixel */ + t0 = (bayer[0] + bayer[2] + bayer[width * 2] + + bayer[width * 2 + 2] + 2) >> 2; + t1 = (bayer[1] + bayer[width] + + bayer[width + 2] + bayer[width * 2 + 1] + + 2) >> 2; + if (blue_line) { + *bgr++ = t0; + *bgr++ = t1; + *bgr++ = bayer[width + 1]; + } else { + *bgr++ = bayer[width + 1]; + *bgr++ = t1; + *bgr++ = t0; + } + /* write last pixel */ + t0 = (bayer[2] + bayer[width * 2 + 2] + 1) >> 1; + if (blue_line) { + *bgr++ = t0; + *bgr++ = bayer[width + 2]; + *bgr++ = bayer[width + 1]; + } else { + *bgr++ = bayer[width + 1]; + *bgr++ = bayer[width + 2]; + *bgr++ = t0; + } + bayer++; + } else { + /* write last pixel */ + t0 = (bayer[0] + bayer[width * 2] + 1) >> 1; + t1 = (bayer[1] + bayer[width * 2 + 1] + bayer[width] + 1) / 3; + if (blue_line) { + *bgr++ = t0; + *bgr++ = t1; + *bgr++ = bayer[width + 1]; + } else { + *bgr++ = bayer[width + 1]; + *bgr++ = t1; + *bgr++ = t0; + } + } + + /* skip 2 border pixels */ + bayer += 2; + + blue_line = !blue_line; + start_with_green = !start_with_green; + } + + /* render the last line */ + v4lconvert_border_bayer_line_to_bgr24(bayer + width, bayer, bgr, width, + !start_with_green, !blue_line); +} + +static void v4lconvert_border_bayer_line_to_y( + const unsigned char* bayer, const unsigned char* adjacent_bayer, + unsigned char *y, int width, int start_with_green, int blue_line) +{ + int t0, t1; + + if (start_with_green) { + /* First pixel */ + if (blue_line) { + *y++ = (8453*adjacent_bayer[0] + 16594*bayer[0] + 3223*bayer[1] + 524288) + >> 15; + } else { + *y++ = (8453*bayer[1] + 16594*bayer[0] + 3223*adjacent_bayer[0] + 524288) + >> 15; + } + /* Second pixel */ + t0 = bayer[0] + bayer[2] + adjacent_bayer[1]; + t1 = adjacent_bayer[0] + adjacent_bayer[2]; + if (blue_line) { + *y++ = (4226*t1 + 5531*t0 + 3223*bayer[1] + 524288) >> 15; + } else { + *y++ = (8453*bayer[1] + 5531*t0 + 1611*t1 + 524288) >> 15; + } + bayer++; + adjacent_bayer++; + width -= 2; + } else { + /* First pixel */ + t0 = bayer[1] + adjacent_bayer[0]; + if (blue_line) { + *y++ = (8453*adjacent_bayer[1] + 8297*t0 + 3223*bayer[0] + 524288) + >> 15; + } else { + *y++ = (8453*bayer[0] + 8297*t0 + 3223*adjacent_bayer[1] + 524288) + >> 15; + } + width--; + } + + if (blue_line) { + for ( ; width > 2; width -= 2) { + t0 = bayer[0] + bayer[2]; + *y++ = (8453*adjacent_bayer[1] + 16594*bayer[1] + 1611*t0 + 524288) + >> 15; + bayer++; + adjacent_bayer++; + + t0 = bayer[0] + bayer[2] + adjacent_bayer[1]; + t1 = adjacent_bayer[0] + adjacent_bayer[2]; + *y++ = (4226*t1 + 5531*t0 + 3223*bayer[1] + 524288) >> 15; + bayer++; + adjacent_bayer++; + } + } else { + for ( ; width > 2; width -= 2) { + t0 = bayer[0] + bayer[2]; + *y++ = (4226*t0 + 16594*bayer[1] + 3223*adjacent_bayer[1] + 524288) + >> 15; + bayer++; + adjacent_bayer++; + + t0 = bayer[0] + bayer[2] + adjacent_bayer[1]; + t1 = adjacent_bayer[0] + adjacent_bayer[2]; + *y++ = (8453*bayer[1] + 5531*t0 + 1611*t1 + 524288) >> 15; + bayer++; + adjacent_bayer++; + } + } + + if (width == 2) { + /* Second to last pixel */ + t0 = bayer[0] + bayer[2]; + if (blue_line) { + *y++ = (8453*adjacent_bayer[1] + 16594*bayer[1] + 1611*t0 + 524288) + >> 15; + } else { + *y++ = (4226*t0 + 16594*bayer[1] + 3223*adjacent_bayer[1] + 524288) + >> 15; + } + /* Last pixel */ + t0 = bayer[1] + adjacent_bayer[2]; + if (blue_line) { + *y++ = (8453*adjacent_bayer[1] + 8297*t0 + 3223*bayer[2] + 524288) + >> 15; + } else { + *y++ = (8453*bayer[2] + 8297*t0 + 3223*adjacent_bayer[1] + 524288) + >> 15; + } + } else { + /* Last pixel */ + if (blue_line) { + *y++ = (8453*adjacent_bayer[1] + 16594*bayer[1] + 3223*bayer[0] + 524288) + >> 15; + } else { + *y++ = (8453*bayer[0] + 16594*bayer[1] + 3223*adjacent_bayer[1] + 524288) + >> 15; + } + } +} + +void v4lconvert_bayer_to_yuv420(const unsigned char *bayer, + unsigned char *yuv, int width, int height, unsigned int pixfmt) +{ + int blue_line = 0, start_with_green = 0, x, y; + unsigned char *ydst = yuv; + unsigned char *udst = yuv + width * height; + unsigned char *vdst = udst + width * height / 4; + + /* First calculate the u and v planes 2x2 pixels at a time */ + switch (pixfmt) { + case V4L2_PIX_FMT_SBGGR8: + for (y = 0; y < height; y += 2) { + for (x = 0; x < width; x += 2) { + int b, g, r; + b = bayer[x]; + g = bayer[x+1]; + g += bayer[x+width]; + r = bayer[x+width+1]; + *udst++ = (-4878 * r - 4789 * g + 14456 * b + 4210688) >> 15; + *vdst++ = (14456 * r - 6052 * g - 2351 * b + 4210688) >> 15; + } + bayer += 2 * width; + } + blue_line = 1; + break; + + case V4L2_PIX_FMT_SRGGB8: + for (y = 0; y < height; y += 2) { + for (x = 0; x < width; x += 2) { + int b, g, r; + r = bayer[x]; + g = bayer[x+1]; + g += bayer[x+width]; + b = bayer[x+width+1]; + *udst++ = (-4878 * r - 4789 * g + 14456 * b + 4210688) >> 15; + *vdst++ = (14456 * r - 6052 * g - 2351 * b + 4210688) >> 15; + } + bayer += 2 * width; + } + break; + + case V4L2_PIX_FMT_SGBRG8: + for (y = 0; y < height; y += 2) { + for (x = 0; x < width; x += 2) { + int b, g, r; + g = bayer[x]; + b = bayer[x+1]; + r = bayer[x+width]; + g += bayer[x+width+1]; + *udst++ = (-4878 * r - 4789 * g + 14456 * b + 4210688) >> 15; + *vdst++ = (14456 * r - 6052 * g - 2351 * b + 4210688) >> 15; + } + bayer += 2 * width; + } + blue_line = 1; + start_with_green = 1; + break; + + case V4L2_PIX_FMT_SGRBG8: + for (y = 0; y < height; y += 2) { + for (x = 0; x < width; x += 2) { + int b, g, r; + g = bayer[x]; + r = bayer[x+1]; + b = bayer[x+width]; + g += bayer[x+width+1]; + *udst++ = (-4878 * r - 4789 * g + 14456 * b + 4210688) >> 15; + *vdst++ = (14456 * r - 6052 * g - 2351 * b + 4210688) >> 15; + } + bayer += 2 * width; + } + start_with_green = 1; + break; + } + + bayer -= width * height; + + /* render the first line */ + v4lconvert_border_bayer_line_to_y(bayer, bayer + width, ydst, width, + start_with_green, blue_line); + ydst += width; + + /* reduce height by 2 because of the border */ + for (height -= 2; height; height--) { + int t0, t1; + /* (width - 2) because of the border */ + const unsigned char *bayerEnd = bayer + (width - 2); + + if (start_with_green) { + t0 = bayer[1] + bayer[width * 2 + 1]; + /* Write first pixel */ + t1 = bayer[0] + bayer[width * 2] + bayer[width + 1]; + if (blue_line) + *ydst++ = (8453*bayer[width] + 5516*t1 + 1661*t0 + 524288) >> 15; + else + *ydst++ = (4226*t0 + 5516*t1 + 3223*bayer[width] + 524288) >> 15; + + /* Write second pixel */ + t1 = bayer[width] + bayer[width + 2]; + if (blue_line) + *ydst++ = (4226*t1 + 16594*bayer[width+1] + 1611*t0 + 524288) >> 15; + else + *ydst++ = (4226*t0 + 16594*bayer[width+1] + 1611*t1 + 524288) >> 15; + bayer++; + } else { + /* Write first pixel */ + t0 = bayer[0] + bayer[width * 2]; + if (blue_line) { + *ydst++ = (8453*bayer[width+1] + 16594*bayer[width] + 1661*t0 + + 524288) >> 15; + } else { + *ydst++ = (4226*t0 + 16594*bayer[width] + 3223*bayer[width+1] + + 524288) >> 15; + } + } + + if (blue_line) { + for (; bayer <= bayerEnd - 2; bayer += 2) { + t0 = bayer[0] + bayer[2] + bayer[width * 2] + bayer[width * 2 + 2]; + t1 = bayer[1] + bayer[width] + bayer[width + 2] + bayer[width * 2 + 1]; + *ydst++ = (8453*bayer[width+1] + 4148*t1 + 806*t0 + 524288) >> 15; + + t0 = bayer[2] + bayer[width * 2 + 2]; + t1 = bayer[width + 1] + bayer[width + 3]; + *ydst++ = (4226*t1 + 16594*bayer[width+2] + 1611*t0 + 524288) >> 15; + } + } else { + for (; bayer <= bayerEnd - 2; bayer += 2) { + t0 = bayer[0] + bayer[2] + bayer[width * 2] + bayer[width * 2 + 2]; + t1 = bayer[1] + bayer[width] + bayer[width + 2] + bayer[width * 2 + 1]; + *ydst++ = (2113*t0 + 4148*t1 + 3223*bayer[width+1] + 524288) >> 15; + + t0 = bayer[2] + bayer[width * 2 + 2]; + t1 = bayer[width + 1] + bayer[width + 3]; + *ydst++ = (4226*t0 + 16594*bayer[width+2] + 1611*t1 + 524288) >> 15; + } + } + + if (bayer < bayerEnd) { + /* Write second to last pixel */ + t0 = bayer[0] + bayer[2] + bayer[width * 2] + bayer[width * 2 + 2]; + t1 = bayer[1] + bayer[width] + bayer[width + 2] + bayer[width * 2 + 1]; + if (blue_line) + *ydst++ = (8453*bayer[width+1] + 4148*t1 + 806*t0 + 524288) >> 15; + else + *ydst++ = (2113*t0 + 4148*t1 + 3223*bayer[width+1] + 524288) >> 15; + + /* write last pixel */ + t0 = bayer[2] + bayer[width * 2 + 2]; + if (blue_line) { + *ydst++ = (8453*bayer[width+1] + 16594*bayer[width+2] + 1661*t0 + + 524288) >> 15; + } else { + *ydst++ = (4226*t0 + 16594*bayer[width+2] + 3223*bayer[width+1] + + 524288) >> 15; + } + bayer++; + } else { + /* write last pixel */ + t0 = bayer[0] + bayer[width * 2]; + t1 = bayer[1] + bayer[width * 2 + 1] + bayer[width]; + if (blue_line) + *ydst++ = (8453*bayer[width+1] + 5516*t1 + 1661*t0 + 524288) >> 15; + else + *ydst++ = (4226*t0 + 5516*t1 + 3223*bayer[width+1] + 524288) >> 15; + } + + /* skip 2 border pixels */ + bayer += 2; + + blue_line = !blue_line; + start_with_green = !start_with_green; + } + + /* render the last line */ + v4lconvert_border_bayer_line_to_y(bayer + width, bayer, ydst, width, + !start_with_green, !blue_line); +} diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/jidctflt.c b/v4l2-apps/lib/libv4l/libv4lconvert/jidctflt.c new file mode 100644 index 000000000..ba70309c9 --- /dev/null +++ b/v4l2-apps/lib/libv4l/libv4lconvert/jidctflt.c @@ -0,0 +1,286 @@ +/* + * jidctflt.c + * + * Copyright (C) 1994-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * + * The authors make NO WARRANTY or representation, either express or implied, + * with respect to this software, its quality, accuracy, merchantability, or + * fitness for a particular purpose. This software is provided "AS IS", and you, + * its user, assume the entire risk as to its quality and accuracy. + * + * This software is copyright (C) 1991-1998, Thomas G. Lane. + * All Rights Reserved except as specified below. + * + * Permission is hereby granted to use, copy, modify, and distribute this + * software (or portions thereof) for any purpose, without fee, subject to these + * conditions: + * (1) If any part of the source code for this software is distributed, then this + * README file must be included, with this copyright and no-warranty notice + * unaltered; and any additions, deletions, or changes to the original files + * must be clearly indicated in accompanying documentation. + * (2) If only executable code is distributed, then the accompanying + * documentation must state that "this software is based in part on the work of + * the Independent JPEG Group". + * (3) Permission for use of this software is granted only if the user accepts + * full responsibility for any undesirable consequences; the authors accept + * NO LIABILITY for damages of any kind. + * + * These conditions apply to any software derived from or based on the IJG code, + * not just to the unmodified library. If you use our work, you ought to + * acknowledge us. + * + * Permission is NOT granted for the use of any IJG author's name or company name + * in advertising or publicity relating to this software or products derived from + * it. This software may be referred to only as "the Independent JPEG Group's + * software". + * + * We specifically permit and encourage the use of this software as the basis of + * commercial products, provided that all warranty or liability claims are + * assumed by the product vendor. + * + * + * This file contains a floating-point implementation of the + * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine + * must also perform dequantization of the input coefficients. + * + * This implementation should be more accurate than either of the integer + * IDCT implementations. However, it may not give the same results on all + * machines because of differences in roundoff behavior. Speed will depend + * on the hardware's floating point capacity. + * + * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + * on each row (or vice versa, but it's more convenient to emit a row at + * a time). Direct algorithms are also available, but they are much more + * complex and seem not to be any faster when reduced to code. + * + * This implementation is based on Arai, Agui, and Nakajima's algorithm for + * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + * Japanese, but the algorithm is described in the Pennebaker & Mitchell + * JPEG textbook (see REFERENCES section in file README). The following code + * is based directly on figure 4-8 in P&M. + * While an 8-point DCT cannot be done in less than 11 multiplies, it is + * possible to arrange the computation so that many of the multiplies are + * simple scalings of the final outputs. These multiplies can then be + * folded into the multiplications or divisions by the JPEG quantization + * table entries. The AA&N method leaves only 5 multiplies and 29 adds + * to be done in the DCT itself. + * The primary disadvantage of this method is that with a fixed-point + * implementation, accuracy is lost due to imprecise representation of the + * scaled quantization values. However, that problem does not arise if + * we use floating point arithmetic. + */ + +#include <stdint.h> +#include "tinyjpeg-internal.h" + +#define FAST_FLOAT float +#define DCTSIZE 8 +#define DCTSIZE2 (DCTSIZE*DCTSIZE) + +#define DEQUANTIZE(coef,quantval) (((FAST_FLOAT) (coef)) * (quantval)) + +#if defined(__GNUC__) && (defined(__i686__)) // || defined(__x86_64__)) + +static inline unsigned char descale_and_clamp(int x, int shift) +{ + __asm__ ( + "add %3,%1\n" + "\tsar %2,%1\n" + "\tsub $-128,%1\n" + "\tcmovl %5,%1\n" /* Use the sub to compare to 0 */ + "\tcmpl %4,%1\n" + "\tcmovg %4,%1\n" + : "=r"(x) + : "0"(x), "Ic"((unsigned char)shift), "ir"(1UL<<(shift-1)), "r" (0xff), "r" (0) + ); + return x; +} + +#else +static inline unsigned char descale_and_clamp(int x, int shift) +{ + x += (1UL<<(shift-1)); + if (x<0) + x = (x >> shift) | ((~(0UL)) << (32-(shift))); + else + x >>= shift; + x += 128; + if (x>255) + return 255; + else if (x<0) + return 0; + else + return x; +} +#endif + +/* + * Perform dequantization and inverse DCT on one block of coefficients. + */ + +void +tinyjpeg_idct_float (struct component *compptr, uint8_t *output_buf, int stride) +{ + FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + FAST_FLOAT tmp10, tmp11, tmp12, tmp13; + FAST_FLOAT z5, z10, z11, z12, z13; + int16_t *inptr; + FAST_FLOAT *quantptr; + FAST_FLOAT *wsptr; + uint8_t *outptr; + int ctr; + FAST_FLOAT workspace[DCTSIZE2]; /* buffers data between passes */ + + /* Pass 1: process columns from input, store into work array. */ + + inptr = compptr->DCT; + quantptr = compptr->Q_table; + wsptr = workspace; + for (ctr = DCTSIZE; ctr > 0; ctr--) { + /* Due to quantization, we will usually find that many of the input + * coefficients are zero, especially the AC terms. We can exploit this + * by short-circuiting the IDCT calculation for any column in which all + * the AC terms are zero. In that case each output is equal to the + * DC coefficient (with scale factor as needed). + * With typical images and quantization tables, half or more of the + * column DCT calculations can be simplified this way. + */ + + if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && + inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 && + inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 && + inptr[DCTSIZE*7] == 0) { + /* AC terms all zero */ + FAST_FLOAT dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + + wsptr[DCTSIZE*0] = dcval; + wsptr[DCTSIZE*1] = dcval; + wsptr[DCTSIZE*2] = dcval; + wsptr[DCTSIZE*3] = dcval; + wsptr[DCTSIZE*4] = dcval; + wsptr[DCTSIZE*5] = dcval; + wsptr[DCTSIZE*6] = dcval; + wsptr[DCTSIZE*7] = dcval; + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + continue; + } + + /* Even part */ + + tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); + tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); + tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); + + tmp10 = tmp0 + tmp2; /* phase 3 */ + tmp11 = tmp0 - tmp2; + + tmp13 = tmp1 + tmp3; /* phases 5-3 */ + tmp12 = (tmp1 - tmp3) * ((FAST_FLOAT) 1.414213562) - tmp13; /* 2*c4 */ + + tmp0 = tmp10 + tmp13; /* phase 2 */ + tmp3 = tmp10 - tmp13; + tmp1 = tmp11 + tmp12; + tmp2 = tmp11 - tmp12; + + /* Odd part */ + + tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); + tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); + tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); + tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); + + z13 = tmp6 + tmp5; /* phase 6 */ + z10 = tmp6 - tmp5; + z11 = tmp4 + tmp7; + z12 = tmp4 - tmp7; + + tmp7 = z11 + z13; /* phase 5 */ + tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */ + + z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */ + tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */ + tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */ + + tmp6 = tmp12 - tmp7; /* phase 2 */ + tmp5 = tmp11 - tmp6; + tmp4 = tmp10 + tmp5; + + wsptr[DCTSIZE*0] = tmp0 + tmp7; + wsptr[DCTSIZE*7] = tmp0 - tmp7; + wsptr[DCTSIZE*1] = tmp1 + tmp6; + wsptr[DCTSIZE*6] = tmp1 - tmp6; + wsptr[DCTSIZE*2] = tmp2 + tmp5; + wsptr[DCTSIZE*5] = tmp2 - tmp5; + wsptr[DCTSIZE*4] = tmp3 + tmp4; + wsptr[DCTSIZE*3] = tmp3 - tmp4; + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + } + + /* Pass 2: process rows from work array, store into output array. */ + /* Note that we must descale the results by a factor of 8 == 2**3. */ + + wsptr = workspace; + outptr = output_buf; + for (ctr = 0; ctr < DCTSIZE; ctr++) { + /* Rows of zeroes can be exploited in the same way as we did with columns. + * However, the column calculation has created many nonzero AC terms, so + * the simplification applies less often (typically 5% to 10% of the time). + * And testing floats for zero is relatively expensive, so we don't bother. + */ + + /* Even part */ + + tmp10 = wsptr[0] + wsptr[4]; + tmp11 = wsptr[0] - wsptr[4]; + + tmp13 = wsptr[2] + wsptr[6]; + tmp12 = (wsptr[2] - wsptr[6]) * ((FAST_FLOAT) 1.414213562) - tmp13; + + tmp0 = tmp10 + tmp13; + tmp3 = tmp10 - tmp13; + tmp1 = tmp11 + tmp12; + tmp2 = tmp11 - tmp12; + + /* Odd part */ + + z13 = wsptr[5] + wsptr[3]; + z10 = wsptr[5] - wsptr[3]; + z11 = wsptr[1] + wsptr[7]; + z12 = wsptr[1] - wsptr[7]; + + tmp7 = z11 + z13; + tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); + + z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */ + tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */ + tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */ + + tmp6 = tmp12 - tmp7; + tmp5 = tmp11 - tmp6; + tmp4 = tmp10 + tmp5; + + /* Final output stage: scale down by a factor of 8 and range-limit */ + + outptr[0] = descale_and_clamp((int)(tmp0 + tmp7), 3); + outptr[7] = descale_and_clamp((int)(tmp0 - tmp7), 3); + outptr[1] = descale_and_clamp((int)(tmp1 + tmp6), 3); + outptr[6] = descale_and_clamp((int)(tmp1 - tmp6), 3); + outptr[2] = descale_and_clamp((int)(tmp2 + tmp5), 3); + outptr[5] = descale_and_clamp((int)(tmp2 - tmp5), 3); + outptr[4] = descale_and_clamp((int)(tmp3 + tmp4), 3); + outptr[3] = descale_and_clamp((int)(tmp3 - tmp4), 3); + + + wsptr += DCTSIZE; /* advance pointer to next row */ + outptr += stride; + } +} + diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert-priv.h b/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert-priv.h new file mode 100644 index 000000000..badb89d62 --- /dev/null +++ b/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert-priv.h @@ -0,0 +1,90 @@ +/* +# (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> + +# 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 __LIBV4LCONVERT_PRIV_H +#define __LIBV4LCONVERT_PRIV_H + +#include <stdio.h> +#include "libv4lconvert.h" +#include "tinyjpeg.h" + +#ifndef V4L2_PIX_FMT_SPCA501 +#define V4L2_PIX_FMT_SPCA501 v4l2_fourcc('S','5','0','1') +#endif + +#ifndef V4L2_PIX_FMT_SPCA561 +#define V4L2_PIX_FMT_SPCA561 v4l2_fourcc('S','5','6','1') +#endif + +#ifndef V4L2_PIX_FMT_PAC207 +#define V4L2_PIX_FMT_PAC207 v4l2_fourcc('P','2','0','7') +#endif + +#ifndef V4L2_PIX_FMT_SGBRG8 +#define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G','B','R','G') +#endif + +#ifndef V4L2_PIX_FMT_SGRBG8 +#define V4L2_PIX_FMT_SGRBG8 v4l2_fourcc('G','R','B','G') +#endif + +#ifndef V4L2_PIX_FMT_SRGGB8 +#define V4L2_PIX_FMT_SRGGB8 v4l2_fourcc('R','G','G','B') +#endif + +#define V4LCONVERT_ERROR_MSG_SIZE 256 + +#define V4LCONVERT_ERR(...) \ + snprintf(data->error_msg, V4LCONVERT_ERROR_MSG_SIZE, \ + "v4l-convert: error " __VA_ARGS__) + + +struct v4lconvert_data { + int fd; + int supported_src_formats; /* bitfield */ + unsigned int no_formats; + char error_msg[V4LCONVERT_ERROR_MSG_SIZE]; + struct jdec_private *jdec; +}; + + +void v4lconvert_yuv420_to_bgr24(const unsigned char *src, unsigned char *dst, + int width, int height); + +void v4lconvert_spca501_to_yuv420(const unsigned char *src, unsigned char *dst, + int width, int height); + +void v4lconvert_spca501_to_bgr24(const unsigned char *src, unsigned char *dst, + int width, int height); + +void v4lconvert_decode_spca561(const unsigned char *src, unsigned char *dst, + int width, int height); + +void v4lconvert_decode_sn9c10x(const unsigned char *src, unsigned char *dst, + int width, int height); + +void v4lconvert_decode_pac207(const unsigned char *src, unsigned char *dst, + int width, int height); + +void v4lconvert_bayer_to_bgr24(const unsigned char *bayer, + unsigned char *rgb, int width, int height, unsigned int pixfmt); + +void v4lconvert_bayer_to_yuv420(const unsigned char *bayer, + unsigned char *yuv, int width, int height, unsigned int pixfmt); + +#endif diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c b/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c new file mode 100644 index 000000000..cc733554c --- /dev/null +++ b/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c @@ -0,0 +1,374 @@ +/* +# (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> + +# 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 +*/ + +#include <errno.h> +#include <string.h> +#include <stdlib.h> +#include <syscall.h> +#include <unistd.h> +#include "libv4lconvert.h" +#include "libv4lconvert-priv.h" + +#define MIN(a,b) (((a)<(b))?(a):(b)) +#define ARRAY_SIZE(x) ((int)sizeof(x)/(int)sizeof((x)[0])) + +/* Note for proper functioning of v4lconvert_enum_fmt the first entries in + supported_src_pixfmts must match with the entries in supported_dst_pixfmts */ +#define SUPPORTED_DST_PIXFMTS \ + V4L2_PIX_FMT_BGR24, \ + V4L2_PIX_FMT_YUV420 + +static const unsigned int supported_src_pixfmts[] = { + SUPPORTED_DST_PIXFMTS, + V4L2_PIX_FMT_MJPEG, + V4L2_PIX_FMT_JPEG, + V4L2_PIX_FMT_SBGGR8, + V4L2_PIX_FMT_SGBRG8, + V4L2_PIX_FMT_SGRBG8, + V4L2_PIX_FMT_SRGGB8, + V4L2_PIX_FMT_SPCA501, + V4L2_PIX_FMT_SPCA561, + V4L2_PIX_FMT_SN9C10X, + V4L2_PIX_FMT_PAC207, +}; + +static const unsigned int supported_dst_pixfmts[] = { + SUPPORTED_DST_PIXFMTS +}; + + +struct v4lconvert_data *v4lconvert_create(int fd) +{ + int i, j; + struct v4lconvert_data *data = calloc(1, sizeof(struct v4lconvert_data)); + + if (!data) + return NULL; + + data->fd = fd; + data->jdec = NULL; + + /* Check supported formats */ + for (i = 0; ; i++) { + struct v4l2_fmtdesc fmt = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE }; + + fmt.index = i; + + if (syscall(SYS_ioctl, fd, VIDIOC_ENUM_FMT, &fmt)) + break; + + for (j = 0; j < ARRAY_SIZE(supported_src_pixfmts); j++) + if (fmt.pixelformat == supported_src_pixfmts[j]) { + data->supported_src_formats |= 1 << j; + break; + } + } + + data->no_formats = i; + + return data; +} + +void v4lconvert_destroy(struct v4lconvert_data *data) +{ + if (data->jdec) { + unsigned char *comps[3] = { NULL, NULL, NULL }; + tinyjpeg_set_components(data->jdec, comps, 3); + tinyjpeg_free(data->jdec); + } + free(data); +} + +/* See libv4lconvert.h for description of in / out parameters */ +int v4lconvert_enum_fmt(struct v4lconvert_data *data, struct v4l2_fmtdesc *fmt) +{ + int i, no_faked_fmts = 0; + unsigned int faked_fmts[ARRAY_SIZE(supported_dst_pixfmts)]; + + if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + fmt->index < data->no_formats || + !data->supported_src_formats) + return syscall(SYS_ioctl, data->fd, VIDIOC_ENUM_FMT, fmt); + + for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++) + if (!(data->supported_src_formats & (1 << i))) { + faked_fmts[no_faked_fmts] = supported_dst_pixfmts[i]; + no_faked_fmts++; + } + + i = fmt->index - data->no_formats; + if (i >= no_faked_fmts) { + errno = EINVAL; + return -1; + } + + fmt->flags = 0; + fmt->pixelformat = faked_fmts[i]; + fmt->description[0] = faked_fmts[i] & 0xff; + fmt->description[1] = (faked_fmts[i] >> 8) & 0xff; + fmt->description[2] = (faked_fmts[i] >> 16) & 0xff; + fmt->description[3] = faked_fmts[i] >> 24; + fmt->description[4] = '\0'; + memset(fmt->reserved, 0, 4); + + return 0; +} + +/* See libv4lconvert.h for description of in / out parameters */ +int v4lconvert_try_format(struct v4lconvert_data *data, + struct v4l2_format *dest_fmt, struct v4l2_format *src_fmt) +{ + int i; + unsigned int closest_fmt_size_diff = -1; + unsigned int desired_pixfmt = dest_fmt->fmt.pix.pixelformat; + struct v4l2_format try_fmt, closest_fmt = { .type = 0 }; + + for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++) + if (supported_dst_pixfmts[i] == desired_pixfmt) + break; + + /* Can we do conversion to the requested format & type? */ + if (i == ARRAY_SIZE(supported_dst_pixfmts) || + dest_fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + int ret = syscall(SYS_ioctl, data->fd, VIDIOC_TRY_FMT, dest_fmt); + if (src_fmt) + *src_fmt = *dest_fmt; + return ret; + } + + for (i = 0; i < ARRAY_SIZE(supported_src_pixfmts); i++) { + /* is this format supported? */ + if (!(data->supported_src_formats & (1 << i))) + continue; + + try_fmt = *dest_fmt; + try_fmt.fmt.pix.pixelformat = supported_src_pixfmts[i]; + + if (!syscall(SYS_ioctl, data->fd, VIDIOC_TRY_FMT, &try_fmt)) + { + if (try_fmt.fmt.pix.pixelformat == supported_src_pixfmts[i]) { + int size_x_diff = abs((int)try_fmt.fmt.pix.width - + (int)dest_fmt->fmt.pix.width); + int size_y_diff = abs((int)try_fmt.fmt.pix.height - + (int)dest_fmt->fmt.pix.height); + unsigned int size_diff = size_x_diff * size_x_diff + + size_y_diff * size_y_diff; + if (size_diff < closest_fmt_size_diff) { + closest_fmt_size_diff = size_diff; + closest_fmt = try_fmt; + } + } + } + } + + if (closest_fmt.type == 0) { + int ret = syscall(SYS_ioctl, data->fd, VIDIOC_TRY_FMT, dest_fmt); + if (src_fmt) + *src_fmt = *dest_fmt; + return ret; + } + + *dest_fmt = closest_fmt; + + /* Are we converting? */ + if (closest_fmt.fmt.pix.pixelformat != desired_pixfmt) { + dest_fmt->fmt.pix.pixelformat = desired_pixfmt; + switch (dest_fmt->fmt.pix.pixelformat) { + case V4L2_PIX_FMT_BGR24: + dest_fmt->fmt.pix.bytesperline = dest_fmt->fmt.pix.width * 3; + dest_fmt->fmt.pix.sizeimage = dest_fmt->fmt.pix.width * + dest_fmt->fmt.pix.height * 3; + break; + case V4L2_PIX_FMT_YUV420: + dest_fmt->fmt.pix.bytesperline = dest_fmt->fmt.pix.width; + dest_fmt->fmt.pix.sizeimage = (dest_fmt->fmt.pix.width * + dest_fmt->fmt.pix.height * 3) / 2; + break; + } + } + + if (src_fmt) + *src_fmt = closest_fmt; + + return 0; +} + +int v4lconvert_convert(struct v4lconvert_data *data, + const struct v4l2_format *src_fmt, /* in */ + const struct v4l2_format *dest_fmt, /* in */ + unsigned char *src, int src_size, unsigned char *dest, int dest_size) +{ + unsigned int header_width, header_height; + int result, needed; + unsigned char *components[3]; + + /* Special case when no conversion is needed */ + if(!memcmp(src_fmt, dest_fmt, sizeof(*src_fmt))) { + int to_copy = MIN(dest_size, src_size); + memcpy(dest, src, to_copy); + return to_copy; + } + + /* sanity check, is the dest buffer large enough? */ + switch (dest_fmt->fmt.pix.pixelformat) { + case V4L2_PIX_FMT_BGR24: + needed = dest_fmt->fmt.pix.width * dest_fmt->fmt.pix.height * 3; + break; + case V4L2_PIX_FMT_YUV420: + needed = (dest_fmt->fmt.pix.width * dest_fmt->fmt.pix.height * 3) / 2; + break; + default: + V4LCONVERT_ERR("Unknown dest format in conversion\n"); + errno = EINVAL; + return -1; + } + + if (dest_size < needed) { + V4LCONVERT_ERR("destination buffer too small\n"); + errno = EFAULT; + return -1; + } + + switch (src_fmt->fmt.pix.pixelformat) { + case V4L2_PIX_FMT_MJPEG: + case V4L2_PIX_FMT_JPEG: + if (!data->jdec) { + data->jdec = tinyjpeg_init(); + if (!data->jdec) { + V4LCONVERT_ERR("out of memory!\n"); + errno = ENOMEM; + return -1; + } + } + tinyjpeg_set_flags(data->jdec, + (src_fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG)? + TINYJPEG_FLAGS_MJPEG_TABLE : 0); + if (tinyjpeg_parse_header(data->jdec, src, src_size)) { + V4LCONVERT_ERR("parsing JPEG header: %s\n", + tinyjpeg_get_errorstring(data->jdec)); + errno = EIO; + return -1; + } + tinyjpeg_get_size(data->jdec, &header_width, &header_height); + + if (header_width != dest_fmt->fmt.pix.width || header_height != dest_fmt->fmt.pix.height) { + V4LCONVERT_ERR("unexpected width / height in JPEG header\n"); + V4LCONVERT_ERR("expected: %dx%d, header: %ux%u\n", + dest_fmt->fmt.pix.width, dest_fmt->fmt.pix.height, + header_width, header_height); + errno = EIO; + return -1; + } + + components[0] = dest; + components[1] = components[0] + dest_fmt->fmt.pix.width * + dest_fmt->fmt.pix.height; + components[2] = components[1] + (dest_fmt->fmt.pix.width * + dest_fmt->fmt.pix.height) / 4; + + if (dest_fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24) { + tinyjpeg_set_components(data->jdec, components, 1); + result = tinyjpeg_decode(data->jdec, TINYJPEG_FMT_BGR24); + } else { + tinyjpeg_set_components(data->jdec, components, 3); + result = tinyjpeg_decode(data->jdec, TINYJPEG_FMT_YUV420P); + } + + if (result) { + V4LCONVERT_ERR("decompressing JPEG: %s\n", + tinyjpeg_get_errorstring(data->jdec)); + errno = EIO; + return -1; + } + break; + + case V4L2_PIX_FMT_SBGGR8: + case V4L2_PIX_FMT_SGBRG8: + case V4L2_PIX_FMT_SGRBG8: + case V4L2_PIX_FMT_SRGGB8: + if (dest_fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24) + v4lconvert_bayer_to_bgr24(src, dest, dest_fmt->fmt.pix.width, + dest_fmt->fmt.pix.height, src_fmt->fmt.pix.pixelformat); + else + v4lconvert_bayer_to_yuv420(src, dest, dest_fmt->fmt.pix.width, + dest_fmt->fmt.pix.height, src_fmt->fmt.pix.pixelformat); + break; + + case V4L2_PIX_FMT_SPCA501: + if (dest_fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24) + v4lconvert_spca501_to_bgr24(src, dest, dest_fmt->fmt.pix.width, + dest_fmt->fmt.pix.height); + else + v4lconvert_spca501_to_yuv420(src, dest, dest_fmt->fmt.pix.width, + dest_fmt->fmt.pix.height); + break; + + /* compressed bayer formats */ + case V4L2_PIX_FMT_SPCA561: + case V4L2_PIX_FMT_SN9C10X: + case V4L2_PIX_FMT_PAC207: + { + unsigned char tmpbuf[dest_fmt->fmt.pix.width*dest_fmt->fmt.pix.height]; + unsigned int bayer_fmt = 0; + + switch (src_fmt->fmt.pix.pixelformat) { + case V4L2_PIX_FMT_SPCA561: + v4lconvert_decode_spca561(src, tmpbuf, dest_fmt->fmt.pix.width, + dest_fmt->fmt.pix.height); + bayer_fmt = V4L2_PIX_FMT_SGBRG8; + break; + case V4L2_PIX_FMT_SN9C10X: + v4lconvert_decode_sn9c10x(src, tmpbuf, dest_fmt->fmt.pix.width, + dest_fmt->fmt.pix.height); + bayer_fmt = V4L2_PIX_FMT_SGBRG8; + break; + case V4L2_PIX_FMT_PAC207: + v4lconvert_decode_pac207(src, tmpbuf, dest_fmt->fmt.pix.width, + dest_fmt->fmt.pix.height); + bayer_fmt = V4L2_PIX_FMT_SBGGR8; + break; + } + + if (dest_fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24) + v4lconvert_bayer_to_bgr24(tmpbuf, dest, dest_fmt->fmt.pix.width, + dest_fmt->fmt.pix.height, bayer_fmt); + else + v4lconvert_bayer_to_yuv420(tmpbuf, dest, dest_fmt->fmt.pix.width, + dest_fmt->fmt.pix.height, bayer_fmt); + break; + } + + case V4L2_PIX_FMT_BGR24: + /* dest must be V4L2_PIX_FMT_YUV420 then */ + printf("FIXME add bgr24 -> yuv420 conversion\n"); + break; + + case V4L2_PIX_FMT_YUV420: + /* dest must be V4L2_PIX_FMT_BGR24 then */ + v4lconvert_yuv420_to_bgr24(src, dest, dest_fmt->fmt.pix.width, + dest_fmt->fmt.pix.height); + break; + } + + return needed; +} + +const char *v4lconvert_get_error_message(struct v4lconvert_data *data) +{ + return data->error_msg; +} diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/pac207.c b/v4l2-apps/lib/libv4l/libv4lconvert/pac207.c new file mode 100644 index 000000000..085d7a772 --- /dev/null +++ b/v4l2-apps/lib/libv4l/libv4lconvert/pac207.c @@ -0,0 +1,418 @@ +/* + +# PAC207 decoder +# Bertrik.Sikken. Thomas Kaiser (C) 2005 +# Copyright (C) 2003 2004 2005 Michel Xhaard + +# 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 + +# Note this code was originally licensed under the GNU GPL instead of the +# GNU LGPL, its license has been changed with permission, see the permission +# mails at the end of this file. + +*/ + +#include <string.h> +#include "libv4lconvert-priv.h" + +#define CLIP(color) (unsigned char)(((color)>0xFF)?0xff:(((color)<0)?0:(color))) + +/* FIXME not threadsafe */ +static int decoder_initialized = 0; + +static struct { + unsigned char is_abs; + unsigned char len; + signed char val; +} table[256]; + +void init_pixart_decoder(void) +{ + int i; + int is_abs, val, len; + for (i = 0; i < 256; i++) { + is_abs = 0; + val = 0; + len = 0; + if ((i & 0xC0) == 0) { + /* code 00 */ + val = 0; + len = 2; + } else if ((i & 0xC0) == 0x40) { + /* code 01 */ + val = -5; + len = 2; + } else if ((i & 0xC0) == 0x80) { + /* code 10 */ + val = +5; + len = 2; + } else if ((i & 0xF0) == 0xC0) { + /* code 1100 */ + val = -10; + len = 4; + } else if ((i & 0xF0) == 0xD0) { + /* code 1101 */ + val = +10; + len = 4; + } else if ((i & 0xF8) == 0xE0) { + /* code 11100 */ + val = -15; + len = 5; + } else if ((i & 0xF8) == 0xE8) { + /* code 11101 */ + val = +15; + len = 5; + } else if ((i & 0xFC) == 0xF0) { + /* code 111100 */ + val = -20; + len = 6; + } else if ((i & 0xFC) == 0xF4) { + /* code 111101 */ + val = +20; + len = 6; + } else if ((i & 0xF8) == 0xF8) { + /* code 11111xxxxxx */ + is_abs = 1; + val = 0; + len = 5; + } + table[i].is_abs = is_abs; + table[i].val = val; + table[i].len = len; + } + decoder_initialized = 1; +} + +static inline unsigned char getByte(const unsigned char *inp, + unsigned int bitpos) +{ + const unsigned char *addr; + addr = inp + (bitpos >> 3); + return (addr[0] << (bitpos & 7)) | (addr[1] >> (8 - (bitpos & 7))); +} + +static inline unsigned short getShort(const unsigned char *pt) +{ + return ((pt[0] << 8) | pt[1]); +} + +static int +pac_decompress_row(const unsigned char *inp, unsigned char *outp, int width) +{ + int col; + int val; + int bitpos; + unsigned char code; + + if (!decoder_initialized) + init_pixart_decoder(); + + /* first two pixels are stored as raw 8-bit */ + *outp++ = inp[2]; + *outp++ = inp[3]; + bitpos = 32; + + /* main decoding loop */ + for (col = 2; col < width; col++) { + /* get bitcode */ + + code = getByte(inp, bitpos); + bitpos += table[code].len; + + /* calculate pixel value */ + if (table[code].is_abs) { + /* absolute value: get 6 more bits */ + code = getByte(inp, bitpos); + bitpos += 6; + *outp++ = code & 0xFC; + } else { + /* relative to left pixel */ + val = outp[-2] + table[code].val; + *outp++ = CLIP(val); + } + } + + /* return line length, rounded up to next 16-bit word */ + return 2 * ((bitpos + 15) / 16); +} + +void v4lconvert_decode_pac207(const unsigned char *inp, unsigned char *outp, + int width, int height) +{ +/* we should received a whole frame with header and EOL marker +in myframe->data and return a GBRG pattern in frame->tmpbuffer +remove the header then copy line by line EOL is set with 0x0f 0xf0 marker +or 0x1e 0xe1 for compressed line*/ + unsigned short word; + int row; + + /* iterate over all rows */ + for (row = 0; row < height; row++) { + word = getShort(inp); + switch (word) { + case 0x0FF0: + memcpy(outp, inp + 2, width); + inp += (2 + width); + break; + case 0x1EE1: + inp += pac_decompress_row(inp, outp, width); + break; + + case 0x2DD2: /* prefix for "stronger" compressed lines, currently the + kernel driver programs the cam so that we should not + get any of these */ + + default: /* corrupt frame */ + /* FIXME add error reporting */ + return; + } + outp += width; + } + + return; +} + + + + +/* +Return-Path: <thomas@kaiser-linux.li> +Received: from koko.hhs.nl ([145.52.2.16] verified) + by hhs.nl (CommuniGate Pro SMTP 4.3.6) + with ESMTP id 88906346 for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 01:17:00 +0200 +Received: from exim (helo=koko) + by koko.hhs.nl with local-smtp (Exim 4.62) + (envelope-from <thomas@kaiser-linux.li>) + id 1KBeEW-0001qu-H6 + for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 01:17:00 +0200 +Received: from [192.87.102.74] (port=41049 helo=filter6-ams.mf.surf.net) + by koko.hhs.nl with esmtp (Exim 4.62) + (envelope-from <thomas@kaiser-linux.li>) + id 1KBeEV-0001qn-2T + for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 01:17:00 +0200 +Received: from smtp0.lie-comtel.li (smtp0.lie-comtel.li [217.173.238.80]) + by filter6-ams.mf.surf.net (8.13.8/8.13.8/Debian-3) with ESMTP id m5PNGwSF007539 + for <j.w.r.degoede@hhs.nl>; Thu, 26 Jun 2008 01:16:58 +0200 +Received: from localhost (localhost.lie-comtel.li [127.0.0.1]) + by smtp0.lie-comtel.li (Postfix) with ESMTP id DDB609FEC1D; + Thu, 26 Jun 2008 00:16:56 +0100 (GMT-1) +X-Virus-Scanned: Virus scanned by amavis at smtp.lie-comtel.li +Received: from [192.168.0.16] (217-173-228-198.cmts.powersurf.li [217.173.228.198]) + by smtp0.lie-comtel.li (Postfix) with ESMTP id 80B589FEC19; + Thu, 26 Jun 2008 00:16:56 +0100 (GMT-1) +Message-ID: <4862D211.3000802@kaiser-linux.li> +Date: Thu, 26 Jun 2008 01:17:37 +0200 +From: Thomas Kaiser <thomas@kaiser-linux.li> +User-Agent: Thunderbird 2.0.0.14 (X11/20080505) +MIME-Version: 1.0 +To: Hans de Goede <j.w.r.degoede@hhs.nl> +CC: Thomas Kaiser <spca5xx@kaiser-linux.li>, bertrik@zonnet.nl, + mxhaard@magic.fr +Subject: Re: pac207 bayer decompression algorithm license question +References: <4862C0A4.3060003@hhs.nl> +In-Reply-To: <4862C0A4.3060003@hhs.nl> +Content-Type: text/plain; charset=ISO-8859-1; format=flowed +Content-Transfer-Encoding: 7bit +X-Canit-CHI2: 0.00 +X-Bayes-Prob: 0.0001 (Score 0, tokens from: @@RPTN) +X-Spam-Score: 0.00 () [Tag at 8.00] +X-CanItPRO-Stream: hhs:j.w.r.degoede@hhs.nl (inherits from hhs:default,base:default) +X-Canit-Stats-ID: 88604132 - 38b3b44cd798 +X-Scanned-By: CanIt (www . roaringpenguin . com) on 192.87.102.74 +X-Anti-Virus: Kaspersky Anti-Virus for MailServers 5.5.2/RELEASE, bases: 25062008 #787666, status: clean + +Hello Hans + +Hans de Goede wrote: +> Hi, +> +> As you may have seen on the mailinglist, I've created a userspace +> library to handle cam specific format handling in userspace where it +> belongs, see: +> http://hansdegoede.livejournal.com/ +Yes, I saw it on the mail list and I think it is a good idea :-) +> +> I would like to also add support for decompressing the pac207's +> compressed bayer to this lib (and remove it from the kernel driver) +> for this I need permission to relicense the decompress code under the +> LGPL (version 2 or later). +Actually, this was done by Bertrik Sikken (bertrik@zonnet.nl), Michel +Xhaard (mxhaard@magic.fr) and me. But Bertrik was the one who found out +how to decode the lines :-) +> +> Can you give me permission for this, or if the code is not yours put +> me in contact with someone who can? +For me it's no problem to release it with LGPL. Maybe you have to ask +the other one's also. +> +> Thanks & Regards, +> +> Hans + +Rgeards, Thomas +*/ + +/* +Return-Path: <mxhaard@magic.fr> +Received: from koko.hhs.nl ([145.52.2.16] verified) + by hhs.nl (CommuniGate Pro SMTP 4.3.6) + with ESMTP id 88910192 for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 09:15:37 +0200 +Received: from exim (helo=koko) + by koko.hhs.nl with local-smtp (Exim 4.62) + (envelope-from <mxhaard@magic.fr>) + id 1KBlhh-0006Fi-Oe + for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 09:15:37 +0200 +Received: from [194.171.167.220] (port=54180 helo=filter4-til.mf.surf.net) + by koko.hhs.nl with esmtp (Exim 4.62) + (envelope-from <mxhaard@magic.fr>) + id 1KBlhh-0006Fd-FY + for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 09:15:37 +0200 +Received: from smtp4-g19.free.fr (smtp4-g19.free.fr [212.27.42.30]) + by filter4-til.mf.surf.net (8.13.8/8.13.8/Debian-3) with ESMTP id m5Q7FY1I006360 + for <j.w.r.degoede@hhs.nl>; Thu, 26 Jun 2008 09:15:34 +0200 +Received: from smtp4-g19.free.fr (localhost.localdomain [127.0.0.1]) + by smtp4-g19.free.fr (Postfix) with ESMTP id 51C683EA0E7; + Thu, 26 Jun 2008 09:15:34 +0200 (CEST) +Received: from [192.168.1.11] (lns-bzn-54-82-251-105-53.adsl.proxad.net [82.251.105.53]) + by smtp4-g19.free.fr (Postfix) with ESMTP id 1149E3EA0C7; + Thu, 26 Jun 2008 09:15:34 +0200 (CEST) +From: Michel Xhaard <mxhaard@magic.fr> +To: Hans de Goede <j.w.r.degoede@hhs.nl> +Subject: Re: pac207 bayer decompression algorithm license question +Date: Thu, 26 Jun 2008 11:15:32 +0200 +User-Agent: KMail/1.9.5 +Cc: bertrik@zonnet.nl, spca5xx@kaiser-linux.li, + "Jean-Francois Moine" <moinejf@free.fr> +References: <48633F02.3040108@hhs.nl> +In-Reply-To: <48633F02.3040108@hhs.nl> +MIME-Version: 1.0 +Content-Type: text/plain; + charset="iso-8859-1" +Content-Transfer-Encoding: quoted-printable +Content-Disposition: inline +Message-Id: <200806261115.32909.mxhaard@magic.fr> +X-Canit-CHI2: 0.00 +X-Bayes-Prob: 0.0001 (Score 0, tokens from: @@RPTN) +X-Spam-Score: 0.00 () [Tag at 8.00] +X-CanItPRO-Stream: hhs:j.w.r.degoede@hhs.nl (inherits from hhs:default,base:default) +X-Canit-Stats-ID: 88656338 - 0dde233cb8b5 +X-Scanned-By: CanIt (www . roaringpenguin . com) on 194.171.167.220 +X-Anti-Virus: Kaspersky Anti-Virus for MailServers 5.5.2/RELEASE, bases: 26062008 #787720, status: clean + +Le jeudi 26 juin 2008 09:02, Hans de Goede a =E9crit=A0: +> Hi, +> +> As you may have seen on the mailinglist, I've created a userspace library +> to handle cam specific format handling in userspace, see: +> http://hansdegoede.livejournal.com/ +> +> I would like to also add support for decompressing the pac207's compressed +> bayer to this lib (and remove it from the kernel driver) and I've heard +> from Thomas Kaiser that you are a co-author of the decompression code. In +> order to add support for decompressing pac207 compressed bayer to libv4l I +> need permission to relicense the decompression code under the LGPL (versi= +on +> 2 or later). +> +> Can you give me permission for this? +> +> Thanks & Regards, +> +> Hans +> +> +> +> p.s. +> +> Thomas has already given permission. + +=46or me it is ok and a good idea for all free world familly ;-). +Bests regards +=2D-=20 +Michel Xhaard +http://mxhaard.free.fr +*/ + +/* +Return-Path: <bertrik@sikken.nl> +Received: from koko.hhs.nl ([145.52.2.16] verified) + by hhs.nl (CommuniGate Pro SMTP 4.3.6) + with ESMTP id 88940205 for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 22:03:30 +0200 +Received: from exim (helo=koko) + by koko.hhs.nl with local-smtp (Exim 4.62) + (envelope-from <bertrik@sikken.nl>) + id 1KBxgo-0003Dj-ET + for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 22:03:30 +0200 +Received: from [192.87.102.69] (port=51992 helo=filter1-ams.mf.surf.net) + by koko.hhs.nl with esmtp (Exim 4.62) + (envelope-from <bertrik@sikken.nl>) + id 1KBxgo-0003Dd-5i + for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 22:03:30 +0200 +Received: from pelian.kabelfoon.nl (pelian3.kabelfoon.nl [62.45.45.106]) + by filter1-ams.mf.surf.net (8.13.8/8.13.8/Debian-3) with ESMTP id m5QK3ThE007720 + for <j.w.r.degoede@hhs.nl>; Thu, 26 Jun 2008 22:03:29 +0200 +Received: from [192.168.1.1] (062-015-045-062.dynamic.caiway.nl [62.45.15.62]) + by pelian.kabelfoon.nl (Postfix) with ESMTP id 9239B428100 + for <j.w.r.degoede@hhs.nl>; Thu, 26 Jun 2008 22:03:29 +0200 (CEST) +Message-ID: <4863F611.80104@sikken.nl> +Date: Thu, 26 Jun 2008 22:03:29 +0200 +From: Bertrik Sikken <bertrik@sikken.nl> +User-Agent: Thunderbird 2.0.0.14 (Windows/20080421) +MIME-Version: 1.0 +To: Hans de Goede <j.w.r.degoede@hhs.nl> +Subject: Re: pac207 bayer decompression algorithm license question +References: <48633F02.3040108@hhs.nl> +In-Reply-To: <48633F02.3040108@hhs.nl> +X-Enigmail-Version: 0.95.6 +Content-Type: text/plain; charset=ISO-8859-1; format=flowed +Content-Transfer-Encoding: 7bit +X-Canit-CHI2: 0.00 +X-Bayes-Prob: 0.0001 (Score 0, tokens from: @@RPTN) +X-Spam-Score: 0.00 () [Tag at 8.00] +X-CanItPRO-Stream: hhs:j.w.r.degoede@hhs.nl (inherits from hhs:default,base:default) +X-Canit-Stats-ID: 88938005 - ef1f0836ffc7 +X-Scanned-By: CanIt (www . roaringpenguin . com) on 192.87.102.69 +X-Anti-Virus: Kaspersky Anti-Virus for MailServers 5.5.2/RELEASE, bases: 26062008 #787877, status: clean + +Hallo Hans, + +Hans de Goede wrote: +> Hi, +> +> As you may have seen on the mailinglist, I've created a userspace +> library to +> handle cam specific format handling in userspace, see: +> http://hansdegoede.livejournal.com/ + +O leuk, zoiets is naar mijn idee precies wat er nodig is voor webcam +support onder linux. Ik ben een jaar of 3 geleden heel actief geweest +met een aantal webcams, maar doe er tegenwoordig helemaal niets meer +aan. + +> I would like to also add support for decompressing the pac207's compressed +> bayer to this lib (and remove it from the kernel driver) and I've heard +> from Thomas Kaiser that you are a co-author of the decompression code. +> In order to add support for decompressing pac207 compressed bayer to +> libv4l I need +> permission to relicense the decompression code under the LGPL (version 2 +> or later). +> +> Can you give me permission for this? + +Ja, vind ik goed. + +Vriendelijke groet, +Bertrik +*/ diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/rgbyuv.c b/v4l2-apps/lib/libv4l/libv4lconvert/rgbyuv.c new file mode 100644 index 000000000..79c8ecb35 --- /dev/null +++ b/v4l2-apps/lib/libv4l/libv4lconvert/rgbyuv.c @@ -0,0 +1,82 @@ +/* + +# RGB <-> YUV conversion routines + +# (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> + +# 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 + +*/ + +#define RGB2YUV(r,g,b,y,u,v) \ + (y) = (( 8453*(r) + 16594*(g) + 3223*(b) + 524288) >> 15); \ + (u) = (( -4878*(r) - 9578*(g) + 14456*(b) + 4210688) >> 15); \ + (v) = (( 14456*(r) - 12105*(g) - 2351*(b) + 4210688) >> 15) + +#define YUV2R(y, u, v) ({ \ + int r = (y) + ((((v)-128)*1436) >> 10); r > 255 ? 255 : r < 0 ? 0 : r; }) +#define YUV2G(y, u, v) ({ \ + int g = (y) - ((((u)-128)*352 + ((v)-128)*731) >> 10); g > 255 ? 255 : g < 0 ? 0 : g; }) +#define YUV2B(y, u, v) ({ \ + int b = (y) + ((((u)-128)*1814) >> 10); b > 255 ? 255 : b < 0 ? 0 : b; }) + +#define CLIP(color) (unsigned char)(((color)>0xFF)?0xff:(((color)<0)?0:(color))) + +void v4lconvert_yuv420_to_bgr24(const unsigned char *src, unsigned char *dest, + int width, int height) +{ + int i,j; + + const unsigned char *ysrc = src; + const unsigned char *usrc = src + width * height; + const unsigned char *vsrc = usrc + (width * height) / 4; + + for (i = 0; i < height; i++) { + for (j = 0; j < width; j += 2) { +#if 1 /* fast slightly less accurate multiplication free code */ + int u1 = (((*usrc - 128) << 7) + (*usrc - 128)) >> 6; + int rg = (((*usrc - 128) << 1) + (*usrc - 128) + + ((*vsrc - 128) << 2) + ((*vsrc - 128) << 1)) >> 3; + int v1 = (((*vsrc - 128) << 1) + (*vsrc - 128)) >> 1; + + *dest++ = CLIP(*ysrc + u1); + *dest++ = CLIP(*ysrc - rg); + *dest++ = CLIP(*ysrc + v1); + ysrc++; + + *dest++ = CLIP(*ysrc + u1); + *dest++ = CLIP(*ysrc - rg); + *dest++ = CLIP(*ysrc + v1); +#else + *dest++ = YUV2B(*ysrc, *usrc, *vsrc); + *dest++ = YUV2G(*ysrc, *usrc, *vsrc); + *dest++ = YUV2R(*ysrc, *usrc, *vsrc); + ysrc++; + + *dest++ = YUV2B(*ysrc, *usrc, *vsrc); + *dest++ = YUV2G(*ysrc, *usrc, *vsrc); + *dest++ = YUV2R(*ysrc, *usrc, *vsrc); +#endif + ysrc++; + usrc++; + vsrc++; + } + /* Rewind u and v for next line */ + if (i&1) { + usrc -= width / 2; + vsrc -= width / 2; + } + } +} diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/sn9c10x.c b/v4l2-apps/lib/libv4l/libv4lconvert/sn9c10x.c new file mode 100644 index 000000000..b23ad4630 --- /dev/null +++ b/v4l2-apps/lib/libv4l/libv4lconvert/sn9c10x.c @@ -0,0 +1,287 @@ +/* +# sonix decoder +# Bertrik.Sikken. (C) 2005 + +# 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 + +# Note this code was originally licensed under the GNU GPL instead of the +# GNU LGPL, its license has been changed with permission, see the permission +# mail at the end of this file. +*/ + +#include "libv4lconvert-priv.h" + +#define CLAMP(x) ((x)<0?0:((x)>255)?255:(x)) + +typedef struct { + int is_abs; + int len; + int val; + int unk; +} code_table_t; + + +/* local storage */ +/* FIXME not thread safe !! */ +static code_table_t table[256]; +static int init_done = 0; + +/* global variable */ +static int sonix_unknown = 0; + +/* + sonix_decompress_init + ===================== + pre-calculates a locally stored table for efficient huffman-decoding. + + Each entry at index x in the table represents the codeword + present at the MSB of byte x. + +*/ +void sonix_decompress_init(void) +{ + int i; + int is_abs, val, len, unk; + + for (i = 0; i < 256; i++) { + is_abs = 0; + val = 0; + len = 0; + unk = 0; + if ((i & 0x80) == 0) { + /* code 0 */ + val = 0; + len = 1; + } + else if ((i & 0xE0) == 0x80) { + /* code 100 */ + val = +4; + len = 3; + } + else if ((i & 0xE0) == 0xA0) { + /* code 101 */ + val = -4; + len = 3; + } + else if ((i & 0xF0) == 0xD0) { + /* code 1101 */ + val = +11; + len = 4; + } + else if ((i & 0xF0) == 0xF0) { + /* code 1111 */ + val = -11; + len = 4; + } + else if ((i & 0xF8) == 0xC8) { + /* code 11001 */ + val = +20; + len = 5; + } + else if ((i & 0xFC) == 0xC0) { + /* code 110000 */ + val = -20; + len = 6; + } + else if ((i & 0xFC) == 0xC4) { + /* code 110001xx: unknown */ + val = 0; + len = 8; + unk = 1; + } + else if ((i & 0xF0) == 0xE0) { + /* code 1110xxxx */ + is_abs = 1; + val = (i & 0x0F) << 4; + len = 8; + } + table[i].is_abs = is_abs; + table[i].val = val; + table[i].len = len; + table[i].unk = unk; + } + + sonix_unknown = 0; + init_done = 1; +} + + +/* + sonix_decompress + ================ + decompresses an image encoded by a SN9C101 camera controller chip. + + IN width + height + inp pointer to compressed frame (with header already stripped) + OUT outp pointer to decompressed frame + + Returns 0 if the operation was successful. + Returns <0 if operation failed. + +*/ +void v4lconvert_decode_sn9c10x(const unsigned char *inp, unsigned char *outp, + int width, int height) +{ + int row, col; + int val; + int bitpos; + unsigned char code; + const unsigned char *addr; + + if (!init_done) + sonix_decompress_init(); + + bitpos = 0; + for (row = 0; row < height; row++) { + + col = 0; + + /* first two pixels in first two rows are stored as raw 8-bit */ + if (row < 2) { + addr = inp + (bitpos >> 3); + code = (addr[0] << (bitpos & 7)) | (addr[1] >> (8 - (bitpos & 7))); + bitpos += 8; + *outp++ = code; + + addr = inp + (bitpos >> 3); + code = (addr[0] << (bitpos & 7)) | (addr[1] >> (8 - (bitpos & 7))); + bitpos += 8; + *outp++ = code; + + col += 2; + } + + while (col < width) { + /* get bitcode from bitstream */ + addr = inp + (bitpos >> 3); + code = (addr[0] << (bitpos & 7)) | (addr[1] >> (8 - (bitpos & 7))); + + /* update bit position */ + bitpos += table[code].len; + + /* update code statistics */ + sonix_unknown += table[code].unk; + + /* calculate pixel value */ + val = table[code].val; + if (!table[code].is_abs) { + /* value is relative to top and left pixel */ + if (col < 2) { + /* left column: relative to top pixel */ + val += outp[-2*width]; + } + else if (row < 2) { + /* top row: relative to left pixel */ + val += outp[-2]; + } + else { + /* main area: average of left pixel and top pixel */ + val += (outp[-2] + outp[-2*width]) / 2; + } + } + + /* store pixel */ + *outp++ = CLAMP(val); + col++; + } + } +} + +/* +Return-Path: <bertrik@sikken.nl> +Received: from koko.hhs.nl ([145.52.2.16] verified) + by hhs.nl (CommuniGate Pro SMTP 4.3.6) + with ESMTP id 89132066 for j.w.r.degoede@hhs.nl; Thu, 03 Jul 2008 15:19:55 +0200 +Received: from exim (helo=koko) + by koko.hhs.nl with local-smtp (Exim 4.62) + (envelope-from <bertrik@sikken.nl>) + id 1KEOj5-0000nq-KR + for j.w.r.degoede@hhs.nl; Thu, 03 Jul 2008 15:19:55 +0200 +Received: from [192.87.102.69] (port=33783 helo=filter1-ams.mf.surf.net) + by koko.hhs.nl with esmtp (Exim 4.62) + (envelope-from <bertrik@sikken.nl>) + id 1KEOj5-0000nj-7r + for j.w.r.degoede@hhs.nl; Thu, 03 Jul 2008 15:19:55 +0200 +Received: from cardassian.kabelfoon.nl (cardassian3.kabelfoon.nl [62.45.45.105]) + by filter1-ams.mf.surf.net (8.13.8/8.13.8/Debian-3) with ESMTP id m63DJsKW032598 + for <j.w.r.degoede@hhs.nl>; Thu, 3 Jul 2008 15:19:54 +0200 +Received: from [192.168.1.1] (044-013-045-062.dynamic.caiway.nl [62.45.13.44]) + by cardassian.kabelfoon.nl (Postfix) with ESMTP id 77761341D9A + for <j.w.r.degoede@hhs.nl>; Thu, 3 Jul 2008 15:19:54 +0200 (CEST) +Message-ID: <486CD1F9.8000307@sikken.nl> +Date: Thu, 03 Jul 2008 15:19:53 +0200 +From: Bertrik Sikken <bertrik@sikken.nl> +User-Agent: Thunderbird 2.0.0.14 (Windows/20080421) +MIME-Version: 1.0 +To: Hans de Goede <j.w.r.degoede@hhs.nl> +Subject: Re: pac207 bayer decompression algorithm license question +References: <48633F02.3040108@hhs.nl> <4863F611.80104@sikken.nl> <486CC6AF.7050509@hhs.nl> +In-Reply-To: <486CC6AF.7050509@hhs.nl> +X-Enigmail-Version: 0.95.6 +Content-Type: text/plain; charset=ISO-8859-1; format=flowed +Content-Transfer-Encoding: 7bit +X-Canit-CHI2: 0.00 +X-Bayes-Prob: 0.0001 (Score 0, tokens from: @@RPTN) +X-Spam-Score: 0.00 () [Tag at 8.00] +X-CanItPRO-Stream: hhs:j.w.r.degoede@hhs.nl (inherits from hhs:default,base:default) +X-Canit-Stats-ID: 90943081 - 6a9ff19e8165 +X-Scanned-By: CanIt (www . roaringpenguin . com) on 192.87.102.69 +X-Anti-Virus: Kaspersky Anti-Virus for MailServers 5.5.2/RELEASE, bases: 03072008 #811719, status: clean + +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA1 + +Hans de Goede wrote: +| Bertrik Sikken wrote: +|> Hallo Hans, +|> +|> Hans de Goede wrote: +|>> I would like to also add support for decompressing the pac207's +|>> compressed +|>> bayer to this lib (and remove it from the kernel driver) and I've +|>> heard from Thomas Kaiser that you are a co-author of the +|>> decompression code. In order to add support for decompressing pac207 +|>> compressed bayer to libv4l I need +|>> permission to relicense the decompression code under the LGPL +|>> (version 2 or later). +|>> +|>> Can you give me permission for this? +|> +|> Ja, vind ik goed. +|> +| +| Thanks! +| +| I'm currently working on adding support for the sn9c10x bayer +| compression to libv4l too, and I noticed this was written by you too. +| +| May I have your permission to relicense the sn9c10x bayer decompression +| code under the LGPL (version 2 or later)? + +I hereby grant you permission to relicense the sn9c10x bayer +decompression code under the LGPL (version 2 or later). + +Kind regards, +Bertrik +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.7 (MingW32) +Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org + +iD8DBQFIbNH5ETD6mlrWxPURAipvAJ9sv1ZpHyb81NMFejr6x0wqHX3i7QCfRDoB +jZi2e5lUjEh5KvS0dqXbi9I= +=KQfR +-----END PGP SIGNATURE----- +*/ diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/spca501.c b/v4l2-apps/lib/libv4l/libv4lconvert/spca501.c new file mode 100644 index 000000000..b0170e7cb --- /dev/null +++ b/v4l2-apps/lib/libv4l/libv4lconvert/spca501.c @@ -0,0 +1,67 @@ +/* +# (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> + +# 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 +*/ + +#include "libv4lconvert-priv.h" + +void v4lconvert_spca501_to_yuv420(const unsigned char *src, unsigned char *dst, + int width, int height) +{ + int i,j; + + for (i = 0; i < height; i += 2) { + unsigned long *lsrc = (unsigned long *)(src + (i / 2) * 3 * width); + + /* -128 - 127 --> 0 - 255 and copy first line Y */ + unsigned long *ldst = (unsigned long *)(dst + i * width); + for (j = 0; j < width; j += sizeof(long)) { + *ldst = *lsrc++; + *ldst++ ^= 0x8080808080808080ULL; + } + + /* -128 - 127 --> 0 - 255 and copy 1 line U */ + ldst = (unsigned long *)(dst + width * height + i * width / 4); + for (j = 0; j < width/2; j += sizeof(long)) { + *ldst = *lsrc++; + *ldst++ ^= 0x8080808080808080ULL; + } + + /* -128 - 127 --> 0 - 255 and copy second line Y */ + ldst = (unsigned long *)(dst + i * width + width); + for (j = 0; j < width; j += sizeof(long)) { + *ldst = *lsrc++; + *ldst++ ^= 0x8080808080808080ULL; + } + + /* -128 - 127 --> 0 - 255 and copy 1 line V */ + ldst = (unsigned long *)(dst + (width * height * 5) / 4 + i * width / 4); + for (j = 0; j < width/2; j += sizeof(long)) { + *ldst = *lsrc++; + *ldst++ ^= 0x8080808080808080ULL; + } + } +} + +/* IMPROVEME (maybe?) make this convert in one go?? */ +void v4lconvert_spca501_to_bgr24(const unsigned char *src, unsigned char *dst, + int width, int height) +{ + unsigned char buf[(width * height * 6) / 4]; + + v4lconvert_spca501_to_yuv420(src, buf, width, height); + v4lconvert_yuv420_to_bgr24(buf, dst, width, height); +} diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/spca561-decompress.c b/v4l2-apps/lib/libv4l/libv4lconvert/spca561-decompress.c new file mode 100644 index 000000000..40b0f90db --- /dev/null +++ b/v4l2-apps/lib/libv4l/libv4lconvert/spca561-decompress.c @@ -0,0 +1,1002 @@ +/* + +# Spca561decoder (C) 2005 Andrzej Szombierski [qq@kuku.eu.org] + +# 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 + +# Note this code was originally licensed under the GNU GPL instead of the +# GNU LGPL, its license has been changed with permission, see the permission +# mail at the end of this file. + +*/ + +/* + * Decoder for compressed spca561 images + * It was developed for "Labtec WebCam Elch 2(SPCA561A)" (046d:0929) + * but it might work with other spca561 cameras + */ +#include <string.h> + +/*fixme: not reentrant */ +static unsigned int bit_bucket; +static const unsigned char *input_ptr; + +static inline void refill(int *bitfill) +{ + if (*bitfill < 8) { + bit_bucket = (bit_bucket << 8) | *(input_ptr++); + *bitfill += 8; + } +} + +static inline int nbits(int *bitfill, int n) +{ + bit_bucket = (bit_bucket << 8) | *(input_ptr++); + *bitfill -= n; + return (bit_bucket >> (*bitfill & 0xff)) & ((1 << n) - 1); +} + +static inline int _nbits(int *bitfill, int n) +{ + *bitfill -= n; + return (bit_bucket >> (*bitfill & 0xff)) & ((1 << n) - 1); +} + +static int fun_A(int *bitfill) +{ + int ret; + static int tab[] = { + 12, 13, 14, 15, 16, 17, 18, 19, -12, -13, -14, -15, + -16, -17, -18, -19, -19 + }; + + ret = tab[nbits(bitfill, 4)]; + + refill(bitfill); + return ret; +} +static int fun_B(int *bitfill) +{ + static int tab1[] = + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 16, 17, + 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 + }; + static int tab[] = + { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, -5, + -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -17, + -18, -19 + }; + unsigned int tmp; + + tmp = nbits(bitfill, 7) - 68; + refill(bitfill); + if (tmp > 47) + return 0xff; + return tab[tab1[tmp]]; +} +static int fun_C(int *bitfill, int gkw) +{ + static int tab1[] = + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 12, 13, + 14, + 15, 16, 17, 18, 19, 20, 21, 22 + }; + static int tab[] = + { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, -9, -10, -11, + -12, -13, -14, -15, -16, -17, -18, -19 + }; + unsigned int tmp; + + if (gkw == 0xfe) { + if (nbits(bitfill, 1) == 0) + return 7; + else + return -8; + } + + if (gkw != 0xff) + return 0xff; + + tmp = nbits(bitfill, 7) - 72; + if (tmp > 43) + return 0xff; + + refill(bitfill); + return tab[tab1[tmp]]; +} +static int fun_D(int *bitfill, int gkw) +{ + if (gkw == 0xfd) { + if (nbits(bitfill, 1) == 0) + return 12; + return -13; + } + + if (gkw == 0xfc) { + if (nbits(bitfill, 1) == 0) + return 13; + return -14; + } + + if (gkw == 0xfe) { + switch (nbits(bitfill, 2)) { + case 0: + return 14; + case 1: + return -15; + case 2: + return 15; + case 3: + return -16; + } + } + + if (gkw == 0xff) { + switch (nbits(bitfill, 3)) { + case 4: + return 16; + case 5: + return -17; + case 6: + return 17; + case 7: + return -18; + case 2: + return _nbits(bitfill, 1) ? 0xed : 0x12; + case 3: + (*bitfill)--; + return 18; + } + return 0xff; + } + return gkw; +} + +static int fun_E(int cur_byte, int *bitfill) +{ + static int tab0[] = { 0, -1, 1, -2, 2, -3, 3, -4 }; + static int tab1[] = { 4, -5, 5, -6, 6, -7, 7, -8 }; + static int tab2[] = { 8, -9, 9, -10, 10, -11, 11, -12 }; + static int tab3[] = { 12, -13, 13, -14, 14, -15, 15, -16 }; + static int tab4[] = { 16, -17, 17, -18, 18, -19, 19, -19 }; + + if ((cur_byte & 0xf0) >= 0x80) { + *bitfill -= 4; + return tab0[(cur_byte >> 4) & 7]; + } + if ((cur_byte & 0xc0) == 0x40) { + *bitfill -= 5; + return tab1[(cur_byte >> 3) & 7]; + + } + if ((cur_byte & 0xe0) == 0x20) { + *bitfill -= 6; + return tab2[(cur_byte >> 2) & 7]; + + } + if ((cur_byte & 0xf0) == 0x10) { + *bitfill -= 7; + return tab3[(cur_byte >> 1) & 7]; + + } + if ((cur_byte & 0xf8) == 8) { + *bitfill -= 8; + return tab4[cur_byte & 7]; + } + return 0xff; +} + +static int fun_F(int cur_byte, int *bitfill) +{ + *bitfill -= 5; + switch (cur_byte & 0xf8) { + case 0x80: + return 0; + case 0x88: + return -1; + case 0x90: + return 1; + case 0x98: + return -2; + case 0xa0: + return 2; + case 0xa8: + return -3; + case 0xb0: + return 3; + case 0xb8: + return -4; + case 0xc0: + return 4; + case 0xc8: + return -5; + case 0xd0: + return 5; + case 0xd8: + return -6; + case 0xe0: + return 6; + case 0xe8: + return -7; + case 0xf0: + return 7; + case 0xf8: + return -8; + } + + *bitfill -= 1; + switch (cur_byte & 0xfc) { + case 0x40: + return 8; + case 0x44: + return -9; + case 0x48: + return 9; + case 0x4c: + return -10; + case 0x50: + return 10; + case 0x54: + return -11; + case 0x58: + return 11; + case 0x5c: + return -12; + case 0x60: + return 12; + case 0x64: + return -13; + case 0x68: + return 13; + case 0x6c: + return -14; + case 0x70: + return 14; + case 0x74: + return -15; + case 0x78: + return 15; + case 0x7c: + return -16; + } + + *bitfill -= 1; + switch (cur_byte & 0xfe) { + case 0x20: + return 16; + case 0x22: + return -17; + case 0x24: + return 17; + case 0x26: + return -18; + case 0x28: + return 18; + case 0x2a: + return -19; + case 0x2c: + return 19; + } + + *bitfill += 7; + return 0xff; +} + +static int internal_spca561_decode(int width, int height, + const unsigned char *inbuf, + unsigned char *outbuf) +{ + /* buffers */ + static int accum[8 * 8 * 8]; + static int i_hits[8 * 8 * 8]; + + const int nbits_A[] = + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, + 1, 1, 1, 1, 1, + 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7, + 7, 7, + 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, + 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, + 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, + 3, 3, + 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + }; + const int tab_A[] = + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, 11, -11, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, + 10, 10, + 255, 254, -4, + -4, -5, -5, -6, -6, -7, -7, -8, -8, -9, -9, -10, -10, -1, + -1, -1, + -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, + -1, -1, + -1, -1, -1, -1, -1, -1, -1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, + 3, 3, 3, + 3, 3, 3, + -2, -2, -2, -2, -2, -2, -2, -2, -3, -3, -3, -3, -3, -3, -3, + -3, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, + 1, 1, 1, 1, + 1 + }; + + const int nbits_B[] = + { 0, 8, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, + 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, + 2, 2, + 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, + 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, + 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + }; + const int tab_B[] = + { 0xff, -4, 3, 3, -3, -3, -3, -3, 2, 2, 2, 2, 2, 2, 2, 2, -2, + -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, + 1, 1, 1, 1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, + -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, + -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, + -1, -1, + -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + }; + + const int nbits_C[] = + { 0, 0, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, + 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, + 3, 3, + 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, + 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, + 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, + 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, + 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, + 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, + 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + }; + const int tab_C[] = + { 0xff, 0xfe, 6, -7, 5, 5, -6, -6, 4, 4, 4, 4, -5, -5, -5, -5, + 3, 3, 3, 3, 3, 3, 3, 3, -4, -4, -4, -4, -4, -4, -4, -4, 2, + 2, 2, 2, + 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, -3, -3, -3, -3, -3, -3, -3, -3, + -3, -3, + -3, -3, -3, + -3, -3, -3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -2, -2, -2, -2, -2, -2, -2, + -2, -2, + -2, -2, -2, + -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + -2, -2, + -2, -2, + -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, + -1, -1, + -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, + -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, + -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, + }; + + const int nbits_D[] = + { 0, 0, 0, 0, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, + 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, + 4, 4, + 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, + 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, + 4, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, + 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, + 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, + 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, + 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 + }; + const int tab_D[] = + { 0xff, 0xfe, 0xfd, 0xfc, 10, -11, 11, -12, 8, 8, -9, -9, 9, 9, + -10, -10, 6, 6, 6, 6, -7, -7, -7, -7, 7, 7, 7, 7, -8, -8, + -8, -8, + 4, 4, 4, 4, + 4, 4, 4, 4, -5, -5, -5, -5, -5, -5, -5, -5, 5, 5, 5, 5, 5, + 5, 5, 5, + -6, -6, + -6, -6, -6, -6, -6, -6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, + 2, 2, -3, + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, + 3, 3, + 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -4, -4, -4, -4, -4, -4, -4, + -4, -4, + -4, -4, -4, + -4, -4, -4, -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, + -1, -1, + -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, + -1, -1, + -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, + 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, -2, -2, -2, -2, -2, -2, -2, -2, + -2, -2, + -2, -2, -2, + -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + -2, -2, + -2, -2 + }; + + /* a_curve[19 + i] = ... [-19..19] => [-160..160] */ + const int a_curve[] = + { -160, -144, -128, -112, -98, -88, -80, -72, -64, -56, -48, + -40, -32, -24, -18, -12, -8, -5, -2, 0, 2, 5, 8, 12, 18, + 24, 32, + 40, 48, 56, 64, + 72, 80, 88, 98, 112, 128, 144, 160 + }; + /* clamp0_255[256 + i] = min(max(i,255),0) */ + const unsigned char clamp0_255[] = + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, + 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, + 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, + 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, + 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, + 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, + 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, + 132, + 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, + 151, 152, 153, 154, 155, + 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, + 169, 170, 171, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, + 186, + 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, + 204, + 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, + 222, + 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, + 241, 242, 243, 244, 245, + 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 255, 255, + 255, + 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, + 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, + 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, + 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, + 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, + 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, + 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, + 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, + 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, + 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, + 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, + 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, + 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, + 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, + 255 + }; + /* abs_clamp15[19 + i] = min(abs(i), 15) */ + const int abs_clamp15[] = + { 15, 15, 15, 15, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, + 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 15, 15, + 15 + }; + /* diff_encoding[256 + i] = ... */ + const int diff_encoding[] = + { 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, + 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, + 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, + 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, + 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, + 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, + 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, + 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 5, 5, 5, 5, 5, 5, + 5, 5, + 5, 5, 5, 5, 5, 3, 3, + 3, 3, 1, 1, 0, 2, 2, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, + 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, + 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, + 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, + 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, + 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, + 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, + 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, + 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, + 6, 6, 6, 6, 6, 6 + }; + + int block; + int bitfill = 0; + int xwidth = width + 6; + int off_up_right = 2 - 2 * xwidth; + int off_up_left = -2 - 2 * xwidth; + int pixel_U = 0, saved_pixel_UR = 0; + int pixel_x = 0, pixel_y = 2; + unsigned char *output_ptr = outbuf; + + memset(i_hits, 0, sizeof(i_hits)); + memset(accum, 0, sizeof(accum)); + + memcpy(outbuf + xwidth * 2 + 3, inbuf + 0x14, width); + memcpy(outbuf + xwidth * 3 + 3, inbuf + 0x14 + width, width); + + input_ptr = inbuf + 0x14 + width * 2; + output_ptr = outbuf + (xwidth) * 4 + 3; + + bit_bucket = 0; + + for (block = 0; block < ((height - 2) * width) / 32; ++block) { + int b_it, var_7 = 0; + int cur_byte; + + refill(&bitfill); + + cur_byte = (bit_bucket >> (bitfill & 7)) & 0xff; + + if ((cur_byte & 0x80) == 0) { + var_7 = 0; + bitfill--; + } else if ((cur_byte & 0xC0) == 0x80) { + var_7 = 1; + bitfill -= 2; + } else if ((cur_byte & 0xc0) == 0xc0) { + var_7 = 2; + bitfill -= 2; + } + + for (b_it = 0; b_it < 32; b_it++) { + int index; + int pixel_L, pixel_UR, pixel_UL; + int multiplier; + int dL, dC, dR; + int gkw; /* God knows what */ + + refill(&bitfill); + cur_byte = bit_bucket >> (bitfill & 7) & 0xff; + + pixel_L = output_ptr[-2]; + pixel_UR = output_ptr[off_up_right]; + pixel_UL = output_ptr[off_up_left]; + + dL = diff_encoding[0x100 + pixel_UL - pixel_L]; + dC = diff_encoding[0x100 + pixel_U - pixel_UL]; + dR = diff_encoding[0x100 + pixel_UR - pixel_U]; + + if (pixel_x < 2) { + pixel_L = pixel_UL = pixel_U = + output_ptr[-xwidth * 2]; + pixel_UR = output_ptr[off_up_right]; + dL = dC = 0; + dR = diff_encoding[0x100 + pixel_UR - + pixel_U]; + } else if (pixel_x > width - 3) + dR = 0; + + multiplier = 4; + index = dR + dC * 8 + dL * 64; + + if (pixel_L + pixel_U * 2 <= 144 + && (pixel_y & 1) == 0 + && (b_it & 3) == 0 && (dR < 5) && (dC < 5) + && (dL < 5)) { + multiplier = 1; + } else if (pixel_L <= 48 + && dL <= 4 && dC <= 4 && dL >= 1 + && dC >= 1) { + multiplier = 2; + } else if (var_7 == 1) { + multiplier = 2; + } else if (dC + dL >= 11 || var_7 == 2) { + multiplier = 8; + } + + if (i_hits[index] < 7) { + bitfill -= nbits_A[cur_byte]; + gkw = tab_A[cur_byte]; + if (gkw == 0xfe) + gkw = fun_A(&bitfill); + } else if (i_hits[index] >= accum[index]) { + bitfill -= nbits_B[cur_byte]; + gkw = tab_B[cur_byte]; + if (cur_byte == 0) + gkw = fun_B(&bitfill); + } else if (i_hits[index] * 2 >= accum[index]) { + bitfill -= nbits_C[cur_byte]; + gkw = tab_C[cur_byte]; + if (cur_byte < 2) + gkw = fun_C(&bitfill, gkw); + } else if (i_hits[index] * 4 >= accum[index]) { + bitfill -= nbits_D[cur_byte]; + gkw = tab_D[cur_byte]; + if (cur_byte < 4) + gkw = fun_D(&bitfill, gkw); + } else if (i_hits[index] * 8 >= accum[index]) { + gkw = fun_E(cur_byte, &bitfill); + } else { + gkw = fun_F(cur_byte, &bitfill); + } + + if (gkw == 0xff) + return -3; + + { + int tmp1, tmp2; + + tmp1 = + (pixel_U + pixel_L) * 3 - pixel_UL * 2; + tmp1 += (tmp1 < 0) ? 3 : 0; + tmp2 = a_curve[19 + gkw] * multiplier; + tmp2 += (tmp2 < 0) ? 1 : 0; + + *(output_ptr++) = + clamp0_255[0x100 + (tmp1 >> 2) - + (tmp2 >> 1)]; + } + pixel_U = saved_pixel_UR; + saved_pixel_UR = pixel_UR; + + if (++pixel_x == width) { + output_ptr += 6; + pixel_x = 0; + pixel_y++; + } + + accum[index] += abs_clamp15[19 + gkw]; + + if (i_hits[index]++ == 15) { + i_hits[index] = 8; + accum[index] /= 2; + } + } + } + return 0; +} + +/* FIXME, change internal_spca561_decode not to need the extra border + around its dest buffer */ +void v4lconvert_decode_spca561(const unsigned char *inbuf, + unsigned char *outbuf, int width, int height) +{ + int i; + static unsigned char tmpbuf[650 * 490]; + if (internal_spca561_decode(width, height, inbuf, tmpbuf) != 0) + return; + for (i = 0; i < height; i++) + memcpy(outbuf + i * width, + tmpbuf + (i + 2) * (width + 6) + 3, width); +} + +/*************** License Change Permission Notice *************** + +Return-Path: <qq@kuku.eu.org> +Received: from koko.hhs.nl ([145.52.2.16] verified) + by hhs.nl (CommuniGate Pro SMTP 4.3.6) + with ESMTP id 88574071 for j.w.r.degoede@hhs.nl; Mon, 16 Jun 2008 16:36:24 +0200 +Received: from exim (helo=koko) + by koko.hhs.nl with local-smtp (Exim 4.62) + (envelope-from <qq@kuku.eu.org>) + id 1K8Fom-0002iJ-3K + for j.w.r.degoede@hhs.nl; Mon, 16 Jun 2008 16:36:24 +0200 +Received: from [192.87.102.74] (port=41377 helo=filter6-ams.mf.surf.net) + by koko.hhs.nl with esmtp (Exim 4.62) + (envelope-from <qq@kuku.eu.org>) + id 1K8Fol-0002iC-Qo + for j.w.r.degoede@hhs.nl; Mon, 16 Jun 2008 16:36:23 +0200 +Received: from kuku.eu.org (pa90.wielkopole.sdi.tpnet.pl [217.99.123.90]) + by filter6-ams.mf.surf.net (8.13.8/8.13.8/Debian-3) with ESMTP id m5GEa55r001787 + for <j.w.r.degoede@hhs.nl>; Mon, 16 Jun 2008 16:36:06 +0200 +Received: (qmail 2243 invoked by uid 500); 16 Jun 2008 14:29:37 -0000 +Date: Mon, 16 Jun 2008 16:29:37 +0200 (CEST) +From: Andrzej Szombierski <qq@kuku.eu.org> +To: Hans de Goede <j.w.r.degoede@hhs.nl> +Subject: Re: spca561 decoder license question +In-Reply-To: <485673B6.4050003@hhs.nl> +Message-ID: <Pine.LNX.4.44L.0806161614560.7665-100000@kuku.eu.org> +References: <485673B6.4050003@hhs.nl> +MIME-Version: 1.0 +Content-Type: TEXT/PLAIN; charset=iso-8859-2 +Content-Transfer-Encoding: QUOTED-PRINTABLE +X-Canit-CHI2: 0.00 +X-Bayes-Prob: 0.0001 (Score 0, tokens from: @@RPTN) +X-Spam-Score: 2.00 (**) [Tag at 6.00] RBL(uceprotect-blacklist.surfnet.nl,2.0) +X-CanItPRO-Stream: hhs:j.w.r.degoede@hhs.nl (inherits from hhs:default,base:default) +X-Canit-Stats-ID: 85673281 - 37e52c8b07bc +X-Scanned-By: CanIt (www . roaringpenguin . com) on 192.87.102.74 +X-Anti-Virus: Kaspersky Anti-Virus for MailServers 5.5.2/RELEASE, bases: 16062008 #776409, status: clean + +On Mon, 16 Jun 2008, Hans de Goede wrote: + +> Hi, +>=20 +> I don't know if you're still subscribed to the spca devel mailing list, s= +o let=20 +> me start with a short intro. +> +> I'm a Linux enthusiast / developer currently helping Jean-Fran=E7ois Moin= +e with=20 +> porting gspca to video4linux2 and cleaning up the code to get it ready fo= +r=20 +> mainline kernel inclusion. +>=20 +> As part of this process the decompression code for all supported cams mus= +t be=20 +> moved to userspace, as doing in kernel decompression is considered unwant= +ed by=20 +> the mainline people (I agree) as it should be done in userspace. +> + +Sounds reasonable. +=20 +> As such I'm working on a library which does decompression of custom cam f= +ormats=20 +> in userspace. +> + +Nice. I hope that the library won't be limited to spca-supported webcams,= +=20 +and as an application developer I would be able to just request RGB data=20 +from any /dev/video*, right? + +> I do not want to license this library as GPL (as the current spca code is= +), as=20 +> it should be usable by as much software as possible. Instead I want to li= +cense=20 +> it under the LGPL version 2.1 or later. + +Also sounds reasonable. + +>=20 +> So my question us my I have your permission to relicense your spca561=20 +> decompression code under the LGPL? +>=20 + +Yes, of course.=20 + +> Thanks & Regards, +>=20 +> Hans +>=20 +> + +--=20 +:: Andrzej Szombierski :: qq@kuku.eu.org :: http://kuku.eu.org :: +:: anszom@bezkitu.com :: radio bez kitu :: http://bezkitu.com :: + +*/ diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/tinyjpeg-internal.h b/v4l2-apps/lib/libv4l/libv4lconvert/tinyjpeg-internal.h new file mode 100644 index 000000000..26844c28a --- /dev/null +++ b/v4l2-apps/lib/libv4l/libv4lconvert/tinyjpeg-internal.h @@ -0,0 +1,121 @@ +/* + * Small jpeg decoder library (Internal header) + * + * Copyright (c) 2006, Luc Saillard <luc@saillard.org> + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * - Neither the name of the author nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef __TINYJPEG_INTERNAL_H_ +#define __TINYJPEG_INTERNAL_H_ + +#include <setjmp.h> + +#define SANITY_CHECK 1 + +struct jdec_private; + +#define HUFFMAN_HASH_NBITS 9 +#define HUFFMAN_HASH_SIZE (1UL<<HUFFMAN_HASH_NBITS) +#define HUFFMAN_HASH_MASK (HUFFMAN_HASH_SIZE-1) + +#define HUFFMAN_TABLES 4 +#define COMPONENTS 3 +#define JPEG_MAX_WIDTH 2048 +#define JPEG_MAX_HEIGHT 2048 + +struct huffman_table +{ + /* Fast look up table, using HUFFMAN_HASH_NBITS bits we can have directly the symbol, + * if the symbol is <0, then we need to look into the tree table */ + short int lookup[HUFFMAN_HASH_SIZE]; + /* code size: give the number of bits of a symbol is encoded */ + unsigned char code_size[HUFFMAN_HASH_SIZE]; + /* some place to store value that is not encoded in the lookup table + * IMPROVEME: Calculate if 256 value is enough to store all values + */ + uint16_t slowtable[16-HUFFMAN_HASH_NBITS][256]; +}; + +struct component +{ + unsigned int Hfactor; + unsigned int Vfactor; + float *Q_table; /* Pointer to the quantisation table to use */ + struct huffman_table *AC_table; + struct huffman_table *DC_table; + short int previous_DC; /* Previous DC coefficient */ + short int DCT[64]; /* DCT coef */ +#if SANITY_CHECK + unsigned int cid; +#endif +}; + + +typedef void (*decode_MCU_fct) (struct jdec_private *priv); +typedef void (*convert_colorspace_fct) (struct jdec_private *priv); + +struct jdec_private +{ + /* Public variables */ + uint8_t *components[COMPONENTS]; + unsigned int width, height; /* Size of the image */ + unsigned int flags; + + /* Private variables */ + const unsigned char *stream_begin, *stream_end; + unsigned int stream_length; + + const unsigned char *stream; /* Pointer to the current stream */ + unsigned int reservoir, nbits_in_reservoir; + + struct component component_infos[COMPONENTS]; + float Q_tables[COMPONENTS][64]; /* quantization tables */ + struct huffman_table HTDC[HUFFMAN_TABLES]; /* DC huffman tables */ + struct huffman_table HTAC[HUFFMAN_TABLES]; /* AC huffman tables */ + int default_huffman_table_initialized; + int restart_interval; + int restarts_to_go; /* MCUs left in this restart interval */ + int last_rst_marker_seen; /* Rst marker is incremented each time */ + + /* Temp space used after the IDCT to store each components */ + uint8_t Y[64*4], Cr[64], Cb[64]; + + jmp_buf jump_state; + /* Internal Pointer use for colorspace conversion, do not modify it !!! */ + uint8_t *plane[COMPONENTS]; + + char error_string[256]; +}; + +#define IDCT tinyjpeg_idct_float +void tinyjpeg_idct_float (struct component *compptr, uint8_t *output_buf, int stride); + +#endif + diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/tinyjpeg.c b/v4l2-apps/lib/libv4l/libv4lconvert/tinyjpeg.c new file mode 100644 index 000000000..b544b1dfa --- /dev/null +++ b/v4l2-apps/lib/libv4l/libv4lconvert/tinyjpeg.c @@ -0,0 +1,2164 @@ +/* + * Small jpeg decoder library + * + * Copyright (c) 2006, Luc Saillard <luc@saillard.org> + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * - Neither the name of the author nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include <errno.h> + +#include "tinyjpeg.h" +#include "tinyjpeg-internal.h" + +enum std_markers { + DQT = 0xDB, /* Define Quantization Table */ + SOF = 0xC0, /* Start of Frame (size information) */ + DHT = 0xC4, /* Huffman Table */ + SOI = 0xD8, /* Start of Image */ + SOS = 0xDA, /* Start of Scan */ + RST = 0xD0, /* Reset Marker d0 -> .. */ + RST7 = 0xD7, /* Reset Marker .. -> d7 */ + EOI = 0xD9, /* End of Image */ + DRI = 0xDD, /* Define Restart Interval */ + APP0 = 0xE0, +}; + +#define cY 0 +#define cCb 1 +#define cCr 2 + +#define BLACK_Y 0 +#define BLACK_U 127 +#define BLACK_V 127 + +#if DEBUG +#if LOG2FILE + +#define trace(fmt, args...) do { \ + FILE *f = fopen("/tmp/jpeg.log", "a"); \ + fprintf(f, fmt, ## args); \ + fflush(f); \ + fclose(f); \ +} while(0) + +#else + +#define trace(fmt, args...) do { \ + fprintf(stderr, fmt, ## args); \ + fflush(stderr); \ +} while(0) +#endif + +#else +#define trace(fmt, args...) do { } while (0) +#endif + +#define error(fmt, args...) do { \ + snprintf(priv->error_string, sizeof(priv->error_string), fmt, ## args); \ + return -1; \ +} while(0) + + +#if 0 +static char *print_bits(unsigned int value, char *bitstr) +{ + int i, j; + i=31; + while (i>0) + { + if (value & (1UL<<i)) + break; + i--; + } + j=0; + while (i>=0) + { + bitstr[j++] = (value & (1UL<<i))?'1':'0'; + i--; + } + bitstr[j] = 0; + return bitstr; +} + +static void print_next_16bytes(int offset, const unsigned char *stream) +{ + trace("%4.4x: %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", + offset, + stream[0], stream[1], stream[2], stream[3], + stream[4], stream[5], stream[6], stream[7], + stream[8], stream[9], stream[10], stream[11], + stream[12], stream[13], stream[14], stream[15]); +} + +#endif + + +static const unsigned char zigzag[64] = +{ + 0, 1, 5, 6, 14, 15, 27, 28, + 2, 4, 7, 13, 16, 26, 29, 42, + 3, 8, 12, 17, 25, 30, 41, 43, + 9, 11, 18, 24, 31, 40, 44, 53, + 10, 19, 23, 32, 39, 45, 52, 54, + 20, 22, 33, 38, 46, 51, 55, 60, + 21, 34, 37, 47, 50, 56, 59, 61, + 35, 36, 48, 49, 57, 58, 62, 63 +}; + +/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */ +/* IMPORTANT: these are only valid for 8-bit data precision! */ +static const unsigned char bits_dc_luminance[17] = +{ + 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 +}; +static const unsigned char val_dc_luminance[] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 +}; + +static const unsigned char bits_dc_chrominance[17] = +{ + 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 +}; +static const unsigned char val_dc_chrominance[] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 +}; + +static const unsigned char bits_ac_luminance[17] = +{ + 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d +}; +static const unsigned char val_ac_luminance[] = +{ + 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, + 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, + 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, + 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, + 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, + 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, + 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, + 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, + 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, + 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa +}; + +static const unsigned char bits_ac_chrominance[17] = +{ + 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 +}; + +static const unsigned char val_ac_chrominance[] = +{ + 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, + 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, + 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, + 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, + 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, + 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, + 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, + 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa +}; + + +/* + * 4 functions to manage the stream + * + * fill_nbits: put at least nbits in the reservoir of bits. + * But convert any 0xff,0x00 into 0xff + * get_nbits: read nbits from the stream, and put it in result, + * bits is removed from the stream and the reservoir is filled + * automaticaly. The result is signed according to the number of + * bits. + * look_nbits: read nbits from the stream without marking as read. + * skip_nbits: read nbits from the stream but do not return the result. + * + * stream: current pointer in the jpeg data (read bytes per bytes) + * nbits_in_reservoir: number of bits filled into the reservoir + * reservoir: register that contains bits information. Only nbits_in_reservoir + * is valid. + * nbits_in_reservoir + * <-- 17 bits --> + * Ex: 0000 0000 1010 0000 1111 0000 <== reservoir + * ^ + * bit 1 + * To get two bits from this example + * result = (reservoir >> 15) & 3 + * + */ +#define fill_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \ + while (nbits_in_reservoir<nbits_wanted) \ + { \ + unsigned char c; \ + if (stream >= priv->stream_end) \ + longjmp(priv->jump_state, -EIO); \ + c = *stream++; \ + reservoir <<= 8; \ + if (c == 0xff && *stream == 0x00) \ + stream++; \ + reservoir |= c; \ + nbits_in_reservoir+=8; \ + } \ +} while(0); + +/* Signed version !!!! */ +#define get_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted,result) do { \ + fill_nbits(reservoir,nbits_in_reservoir,stream,(nbits_wanted)); \ + result = ((reservoir)>>(nbits_in_reservoir-(nbits_wanted))); \ + nbits_in_reservoir -= (nbits_wanted); \ + reservoir &= ((1U<<nbits_in_reservoir)-1); \ + if ((unsigned int)result < (1UL<<((nbits_wanted)-1))) \ + result += (0xFFFFFFFFUL<<(nbits_wanted))+1; \ +} while(0); + +#define look_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted,result) do { \ + fill_nbits(reservoir,nbits_in_reservoir,stream,(nbits_wanted)); \ + result = ((reservoir)>>(nbits_in_reservoir-(nbits_wanted))); \ +} while(0); + +/* To speed up the decoding, we assume that the reservoir have enough bit + * slow version: + * #define skip_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \ + * fill_nbits(reservoir,nbits_in_reservoir,stream,(nbits_wanted)); \ + * nbits_in_reservoir -= (nbits_wanted); \ + * reservoir &= ((1U<<nbits_in_reservoir)-1); \ + * } while(0); + */ +#define skip_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \ + nbits_in_reservoir -= (nbits_wanted); \ + reservoir &= ((1U<<nbits_in_reservoir)-1); \ +} while(0); + + +#define be16_to_cpu(x) (((x)[0]<<8)|(x)[1]) + +static void resync(struct jdec_private *priv); + +/** + * Get the next (valid) huffman code in the stream. + * + * To speedup the procedure, we look HUFFMAN_HASH_NBITS bits and the code is + * lower than HUFFMAN_HASH_NBITS we have automaticaly the length of the code + * and the value by using two lookup table. + * Else if the value is not found, just search (linear) into an array for each + * bits is the code is present. + * + * If the code is not present for any reason, -1 is return. + */ +static int get_next_huffman_code(struct jdec_private *priv, struct huffman_table *huffman_table) +{ + int value, hcode; + unsigned int extra_nbits, nbits; + uint16_t *slowtable; + + look_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, HUFFMAN_HASH_NBITS, hcode); + value = huffman_table->lookup[hcode]; + if (value >= 0) + { + unsigned int code_size = huffman_table->code_size[value]; + skip_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, code_size); + return value; + } + + /* Decode more bits each time ... */ + for (extra_nbits=0; extra_nbits<16-HUFFMAN_HASH_NBITS; extra_nbits++) + { + nbits = HUFFMAN_HASH_NBITS + 1 + extra_nbits; + + look_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, nbits, hcode); + slowtable = huffman_table->slowtable[extra_nbits]; + /* Search if the code is in this array */ + while (slowtable[0]) { + if (slowtable[0] == hcode) { + skip_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, nbits); + return slowtable[1]; + } + slowtable+=2; + } + } + return 0; +} + + + + +/** + * + * Decode a single block that contains the DCT coefficients. + * The table coefficients is already dezigzaged at the end of the operation. + * + */ +static void process_Huffman_data_unit(struct jdec_private *priv, int component) +{ + unsigned char j; + unsigned int huff_code; + unsigned char size_val, count_0; + + struct component *c = &priv->component_infos[component]; + short int DCT[64]; + + /* Initialize the DCT coef table */ + memset(DCT, 0, sizeof(DCT)); + + /* DC coefficient decoding */ + huff_code = get_next_huffman_code(priv, c->DC_table); + if (huff_code) { + get_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, huff_code, DCT[0]); + DCT[0] += c->previous_DC; + c->previous_DC = DCT[0]; + } else { + DCT[0] = c->previous_DC; + } + + + /* AC coefficient decoding */ + j = 1; + while (j<64) + { + huff_code = get_next_huffman_code(priv, c->AC_table); + + size_val = huff_code & 0xF; + count_0 = huff_code >> 4; + + if (size_val == 0) + { /* RLE */ + if (count_0 == 0) + break; /* EOB found, go out */ + else if (count_0 == 0xF) + j += 16; /* skip 16 zeros */ + } + else + { + j += count_0; /* skip count_0 zeroes */ + get_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, size_val, DCT[j]); + j++; + } + } + + for (j = 0; j < 64; j++) + c->DCT[j] = DCT[zigzag[j]]; +} + +/* + * Takes two array of bits, and build the huffman table for size, and code + * + * lookup will return the symbol if the code is less or equal than HUFFMAN_HASH_NBITS. + * code_size will be used to known how many bits this symbol is encoded. + * slowtable will be used when the first lookup didn't give the result. + */ +static void build_huffman_table(const unsigned char *bits, const unsigned char *vals, struct huffman_table *table) +{ + unsigned int i, j, code, code_size, val, nbits; + unsigned char huffsize[257], *hz; + unsigned int huffcode[257], *hc; + int next_free_entry; + + /* + * Build a temp array + * huffsize[X] => numbers of bits to write vals[X] + */ + hz = huffsize; + for (i=1; i<=16; i++) + { + for (j=1; j<=bits[i]; j++) + *hz++ = i; + } + *hz = 0; + + memset(table->lookup, 0xff, sizeof(table->lookup)); + for (i=0; i<(16-HUFFMAN_HASH_NBITS); i++) + table->slowtable[i][0] = 0; + + /* Build a temp array + * huffcode[X] => code used to write vals[X] + */ + code = 0; + hc = huffcode; + hz = huffsize; + nbits = *hz; + while (*hz) + { + while (*hz == nbits) { + *hc++ = code++; + hz++; + } + code <<= 1; + nbits++; + } + + /* + * Build the lookup table, and the slowtable if needed. + */ + next_free_entry = -1; + for (i=0; huffsize[i]; i++) + { + val = vals[i]; + code = huffcode[i]; + code_size = huffsize[i]; + + trace("val=%2.2x code=%8.8x codesize=%2.2d\n", i, code, code_size); + + table->code_size[val] = code_size; + if (code_size <= HUFFMAN_HASH_NBITS) + { + /* + * Good: val can be put in the lookup table, so fill all value of this + * column with value val + */ + int repeat = 1UL<<(HUFFMAN_HASH_NBITS - code_size); + code <<= HUFFMAN_HASH_NBITS - code_size; + while ( repeat-- ) + table->lookup[code++] = val; + + } + else + { + /* Perhaps sorting the array will be an optimization */ + uint16_t *slowtable = table->slowtable[code_size-HUFFMAN_HASH_NBITS-1]; + while(slowtable[0]) + slowtable+=2; + slowtable[0] = code; + slowtable[1] = val; + slowtable[2] = 0; + /* TODO: NEED TO CHECK FOR AN OVERFLOW OF THE TABLE */ + } + + } + +} + +static void build_default_huffman_tables(struct jdec_private *priv) +{ + if ( (priv->flags & TINYJPEG_FLAGS_MJPEG_TABLE) + && priv->default_huffman_table_initialized) + return; + + build_huffman_table(bits_dc_luminance, val_dc_luminance, &priv->HTDC[0]); + build_huffman_table(bits_ac_luminance, val_ac_luminance, &priv->HTAC[0]); + + build_huffman_table(bits_dc_chrominance, val_dc_chrominance, &priv->HTDC[1]); + build_huffman_table(bits_ac_chrominance, val_ac_chrominance, &priv->HTAC[1]); + + priv->default_huffman_table_initialized = 1; +} + + + +/******************************************************************************* + * + * Colorspace conversion routine + * + * + * Note: + * YCbCr is defined per CCIR 601-1, except that Cb and Cr are + * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. + * The conversion equations to be implemented are therefore + * R = Y + 1.40200 * Cr + * G = Y - 0.34414 * Cb - 0.71414 * Cr + * B = Y + 1.77200 * Cb + * + ******************************************************************************/ + +static unsigned char clamp(int i) +{ + if (i<0) + return 0; + else if (i>255) + return 255; + else + return i; +} + + +/** + * YCrCb -> YUV420P (1x1) + * .---. + * | 1 | + * `---' + */ +static void YCrCB_to_YUV420P_1x1(struct jdec_private *priv) +{ + const unsigned char *s, *y; + unsigned char *p; + int i,j; + + p = priv->plane[0]; + y = priv->Y; + for (i=0; i<8; i++) + { + memcpy(p, y, 8); + p+=priv->width; + y+=8; + } + + p = priv->plane[1]; + s = priv->Cb; + for (i=0; i<8; i+=2) + { + for (j=0; j<8; j+=2, s+=2) + *p++ = *s; + s += 8; /* Skip one line */ + p += priv->width/2 - 4; + } + + p = priv->plane[2]; + s = priv->Cr; + for (i=0; i<8; i+=2) + { + for (j=0; j<8; j+=2, s+=2) + *p++ = *s; + s += 8; /* Skip one line */ + p += priv->width/2 - 4; + } +} + +/** + * YCrCb -> YUV420P (2x1) + * .-------. + * | 1 | 2 | + * `-------' + */ +static void YCrCB_to_YUV420P_2x1(struct jdec_private *priv) +{ + unsigned char *p; + const unsigned char *s, *y1; + unsigned int i; + + p = priv->plane[0]; + y1 = priv->Y; + for (i=0; i<8; i++) + { + memcpy(p, y1, 16); + p += priv->width; + y1 += 16; + } + + p = priv->plane[1]; + s = priv->Cb; + for (i=0; i<8; i+=2) + { + memcpy(p, s, 8); + s += 16; /* Skip one line */ + p += priv->width/2; + } + + p = priv->plane[2]; + s = priv->Cr; + for (i=0; i<8; i+=2) + { + memcpy(p, s, 8); + s += 16; /* Skip one line */ + p += priv->width/2; + } +} + + +/** + * YCrCb -> YUV420P (1x2) + * .---. + * | 1 | + * |---| + * | 2 | + * `---' + */ +static void YCrCB_to_YUV420P_1x2(struct jdec_private *priv) +{ + const unsigned char *s, *y; + unsigned char *p; + int i,j; + + p = priv->plane[0]; + y = priv->Y; + for (i=0; i<16; i++) + { + memcpy(p, y, 8); + p+=priv->width; + y+=8; + } + + p = priv->plane[1]; + s = priv->Cb; + for (i=0; i<8; i++) + { + for (j=0; j<8; j+=2, s+=2) + *p++ = *s; + p += priv->width/2 - 4; + } + + p = priv->plane[2]; + s = priv->Cr; + for (i=0; i<8; i++) + { + for (j=0; j<8; j+=2, s+=2) + *p++ = *s; + p += priv->width/2 - 4; + } +} + +/** + * YCrCb -> YUV420P (2x2) + * .-------. + * | 1 | 2 | + * |---+---| + * | 3 | 4 | + * `-------' + */ +static void YCrCB_to_YUV420P_2x2(struct jdec_private *priv) +{ + unsigned char *p; + const unsigned char *s, *y1; + unsigned int i; + + p = priv->plane[0]; + y1 = priv->Y; + for (i=0; i<16; i++) + { + memcpy(p, y1, 16); + p += priv->width; + y1 += 16; + } + + p = priv->plane[1]; + s = priv->Cb; + for (i=0; i<8; i++) + { + memcpy(p, s, 8); + s += 8; + p += priv->width/2; + } + + p = priv->plane[2]; + s = priv->Cr; + for (i=0; i<8; i++) + { + memcpy(p, s, 8); + s += 8; + p += priv->width/2; + } +} + +/** + * YCrCb -> RGB24 (1x1) + * .---. + * | 1 | + * `---' + */ +static void YCrCB_to_RGB24_1x1(struct jdec_private *priv) +{ + const unsigned char *Y, *Cb, *Cr; + unsigned char *p; + int i,j; + int offset_to_next_row; + +#define SCALEBITS 10 +#define ONE_HALF (1UL << (SCALEBITS-1)) +#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5)) + + p = priv->plane[0]; + Y = priv->Y; + Cb = priv->Cb; + Cr = priv->Cr; + offset_to_next_row = priv->width*3 - 8*3; + for (i=0; i<8; i++) { + + for (j=0; j<8; j++) { + + int y, cb, cr; + int add_r, add_g, add_b; + int r, g , b; + + y = (*Y++) << SCALEBITS; + cb = *Cb++ - 128; + cr = *Cr++ - 128; + add_r = FIX(1.40200) * cr + ONE_HALF; + add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; + add_b = FIX(1.77200) * cb + ONE_HALF; + + r = (y + add_r) >> SCALEBITS; + *p++ = clamp(r); + g = (y + add_g) >> SCALEBITS; + *p++ = clamp(g); + b = (y + add_b) >> SCALEBITS; + *p++ = clamp(b); + + } + + p += offset_to_next_row; + } + +#undef SCALEBITS +#undef ONE_HALF +#undef FIX + +} + +/** + * YCrCb -> BGR24 (1x1) + * .---. + * | 1 | + * `---' + */ +static void YCrCB_to_BGR24_1x1(struct jdec_private *priv) +{ + const unsigned char *Y, *Cb, *Cr; + unsigned char *p; + int i,j; + int offset_to_next_row; + +#define SCALEBITS 10 +#define ONE_HALF (1UL << (SCALEBITS-1)) +#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5)) + + p = priv->plane[0]; + Y = priv->Y; + Cb = priv->Cb; + Cr = priv->Cr; + offset_to_next_row = priv->width*3 - 8*3; + for (i=0; i<8; i++) { + + for (j=0; j<8; j++) { + + int y, cb, cr; + int add_r, add_g, add_b; + int r, g , b; + + y = (*Y++) << SCALEBITS; + cb = *Cb++ - 128; + cr = *Cr++ - 128; + add_r = FIX(1.40200) * cr + ONE_HALF; + add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; + add_b = FIX(1.77200) * cb + ONE_HALF; + + b = (y + add_b) >> SCALEBITS; + *p++ = clamp(b); + g = (y + add_g) >> SCALEBITS; + *p++ = clamp(g); + r = (y + add_r) >> SCALEBITS; + *p++ = clamp(r); + + } + + p += offset_to_next_row; + } + +#undef SCALEBITS +#undef ONE_HALF +#undef FIX + +} + + +/** + * YCrCb -> RGB24 (2x1) + * .-------. + * | 1 | 2 | + * `-------' + */ +static void YCrCB_to_RGB24_2x1(struct jdec_private *priv) +{ + const unsigned char *Y, *Cb, *Cr; + unsigned char *p; + int i,j; + int offset_to_next_row; + +#define SCALEBITS 10 +#define ONE_HALF (1UL << (SCALEBITS-1)) +#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5)) + + p = priv->plane[0]; + Y = priv->Y; + Cb = priv->Cb; + Cr = priv->Cr; + offset_to_next_row = priv->width*3 - 16*3; + for (i=0; i<8; i++) { + + for (j=0; j<8; j++) { + + int y, cb, cr; + int add_r, add_g, add_b; + int r, g , b; + + y = (*Y++) << SCALEBITS; + cb = *Cb++ - 128; + cr = *Cr++ - 128; + add_r = FIX(1.40200) * cr + ONE_HALF; + add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; + add_b = FIX(1.77200) * cb + ONE_HALF; + + r = (y + add_r) >> SCALEBITS; + *p++ = clamp(r); + g = (y + add_g) >> SCALEBITS; + *p++ = clamp(g); + b = (y + add_b) >> SCALEBITS; + *p++ = clamp(b); + + y = (*Y++) << SCALEBITS; + r = (y + add_r) >> SCALEBITS; + *p++ = clamp(r); + g = (y + add_g) >> SCALEBITS; + *p++ = clamp(g); + b = (y + add_b) >> SCALEBITS; + *p++ = clamp(b); + + } + + p += offset_to_next_row; + } + +#undef SCALEBITS +#undef ONE_HALF +#undef FIX + +} + +/* + * YCrCb -> BGR24 (2x1) + * .-------. + * | 1 | 2 | + * `-------' + */ +static void YCrCB_to_BGR24_2x1(struct jdec_private *priv) +{ + const unsigned char *Y, *Cb, *Cr; + unsigned char *p; + int i,j; + int offset_to_next_row; + +#define SCALEBITS 10 +#define ONE_HALF (1UL << (SCALEBITS-1)) +#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5)) + + p = priv->plane[0]; + Y = priv->Y; + Cb = priv->Cb; + Cr = priv->Cr; + offset_to_next_row = priv->width*3 - 16*3; + for (i=0; i<8; i++) { + + for (j=0; j<8; j++) { + + int y, cb, cr; + int add_r, add_g, add_b; + int r, g , b; + + cb = *Cb++ - 128; + cr = *Cr++ - 128; + add_r = FIX(1.40200) * cr + ONE_HALF; + add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; + add_b = FIX(1.77200) * cb + ONE_HALF; + + y = (*Y++) << SCALEBITS; + b = (y + add_b) >> SCALEBITS; + *p++ = clamp(b); + g = (y + add_g) >> SCALEBITS; + *p++ = clamp(g); + r = (y + add_r) >> SCALEBITS; + *p++ = clamp(r); + + y = (*Y++) << SCALEBITS; + b = (y + add_b) >> SCALEBITS; + *p++ = clamp(b); + g = (y + add_g) >> SCALEBITS; + *p++ = clamp(g); + r = (y + add_r) >> SCALEBITS; + *p++ = clamp(r); + + } + + p += offset_to_next_row; + } + +#undef SCALEBITS +#undef ONE_HALF +#undef FIX + +} + +/** + * YCrCb -> RGB24 (1x2) + * .---. + * | 1 | + * |---| + * | 2 | + * `---' + */ +static void YCrCB_to_RGB24_1x2(struct jdec_private *priv) +{ + const unsigned char *Y, *Cb, *Cr; + unsigned char *p, *p2; + int i,j; + int offset_to_next_row; + +#define SCALEBITS 10 +#define ONE_HALF (1UL << (SCALEBITS-1)) +#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5)) + + p = priv->plane[0]; + p2 = priv->plane[0] + priv->width*3; + Y = priv->Y; + Cb = priv->Cb; + Cr = priv->Cr; + offset_to_next_row = 2*priv->width*3 - 8*3; + for (i=0; i<8; i++) { + + for (j=0; j<8; j++) { + + int y, cb, cr; + int add_r, add_g, add_b; + int r, g , b; + + cb = *Cb++ - 128; + cr = *Cr++ - 128; + add_r = FIX(1.40200) * cr + ONE_HALF; + add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; + add_b = FIX(1.77200) * cb + ONE_HALF; + + y = (*Y++) << SCALEBITS; + r = (y + add_r) >> SCALEBITS; + *p++ = clamp(r); + g = (y + add_g) >> SCALEBITS; + *p++ = clamp(g); + b = (y + add_b) >> SCALEBITS; + *p++ = clamp(b); + + y = (Y[8-1]) << SCALEBITS; + r = (y + add_r) >> SCALEBITS; + *p2++ = clamp(r); + g = (y + add_g) >> SCALEBITS; + *p2++ = clamp(g); + b = (y + add_b) >> SCALEBITS; + *p2++ = clamp(b); + + } + Y += 8; + p += offset_to_next_row; + p2 += offset_to_next_row; + } + +#undef SCALEBITS +#undef ONE_HALF +#undef FIX + +} + +/* + * YCrCb -> BGR24 (1x2) + * .---. + * | 1 | + * |---| + * | 2 | + * `---' + */ +static void YCrCB_to_BGR24_1x2(struct jdec_private *priv) +{ + const unsigned char *Y, *Cb, *Cr; + unsigned char *p, *p2; + int i,j; + int offset_to_next_row; + +#define SCALEBITS 10 +#define ONE_HALF (1UL << (SCALEBITS-1)) +#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5)) + + p = priv->plane[0]; + p2 = priv->plane[0] + priv->width*3; + Y = priv->Y; + Cb = priv->Cb; + Cr = priv->Cr; + offset_to_next_row = 2*priv->width*3 - 8*3; + for (i=0; i<8; i++) { + + for (j=0; j<8; j++) { + + int y, cb, cr; + int add_r, add_g, add_b; + int r, g , b; + + cb = *Cb++ - 128; + cr = *Cr++ - 128; + add_r = FIX(1.40200) * cr + ONE_HALF; + add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; + add_b = FIX(1.77200) * cb + ONE_HALF; + + y = (*Y++) << SCALEBITS; + b = (y + add_b) >> SCALEBITS; + *p++ = clamp(b); + g = (y + add_g) >> SCALEBITS; + *p++ = clamp(g); + r = (y + add_r) >> SCALEBITS; + *p++ = clamp(r); + + y = (Y[8-1]) << SCALEBITS; + b = (y + add_b) >> SCALEBITS; + *p2++ = clamp(b); + g = (y + add_g) >> SCALEBITS; + *p2++ = clamp(g); + r = (y + add_r) >> SCALEBITS; + *p2++ = clamp(r); + + } + Y += 8; + p += offset_to_next_row; + p2 += offset_to_next_row; + } + +#undef SCALEBITS +#undef ONE_HALF +#undef FIX + +} + + +/** + * YCrCb -> RGB24 (2x2) + * .-------. + * | 1 | 2 | + * |---+---| + * | 3 | 4 | + * `-------' + */ +static void YCrCB_to_RGB24_2x2(struct jdec_private *priv) +{ + const unsigned char *Y, *Cb, *Cr; + unsigned char *p, *p2; + int i,j; + int offset_to_next_row; + +#define SCALEBITS 10 +#define ONE_HALF (1UL << (SCALEBITS-1)) +#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5)) + + p = priv->plane[0]; + p2 = priv->plane[0] + priv->width*3; + Y = priv->Y; + Cb = priv->Cb; + Cr = priv->Cr; + offset_to_next_row = (priv->width*3*2) - 16*3; + for (i=0; i<8; i++) { + + for (j=0; j<8; j++) { + + int y, cb, cr; + int add_r, add_g, add_b; + int r, g , b; + + cb = *Cb++ - 128; + cr = *Cr++ - 128; + add_r = FIX(1.40200) * cr + ONE_HALF; + add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; + add_b = FIX(1.77200) * cb + ONE_HALF; + + y = (*Y++) << SCALEBITS; + r = (y + add_r) >> SCALEBITS; + *p++ = clamp(r); + g = (y + add_g) >> SCALEBITS; + *p++ = clamp(g); + b = (y + add_b) >> SCALEBITS; + *p++ = clamp(b); + + y = (*Y++) << SCALEBITS; + r = (y + add_r) >> SCALEBITS; + *p++ = clamp(r); + g = (y + add_g) >> SCALEBITS; + *p++ = clamp(g); + b = (y + add_b) >> SCALEBITS; + *p++ = clamp(b); + + y = (Y[16-2]) << SCALEBITS; + r = (y + add_r) >> SCALEBITS; + *p2++ = clamp(r); + g = (y + add_g) >> SCALEBITS; + *p2++ = clamp(g); + b = (y + add_b) >> SCALEBITS; + *p2++ = clamp(b); + + y = (Y[16-1]) << SCALEBITS; + r = (y + add_r) >> SCALEBITS; + *p2++ = clamp(r); + g = (y + add_g) >> SCALEBITS; + *p2++ = clamp(g); + b = (y + add_b) >> SCALEBITS; + *p2++ = clamp(b); + } + Y += 16; + p += offset_to_next_row; + p2 += offset_to_next_row; + } + +#undef SCALEBITS +#undef ONE_HALF +#undef FIX + +} + + +/* + * YCrCb -> BGR24 (2x2) + * .-------. + * | 1 | 2 | + * |---+---| + * | 3 | 4 | + * `-------' + */ +static void YCrCB_to_BGR24_2x2(struct jdec_private *priv) +{ + const unsigned char *Y, *Cb, *Cr; + unsigned char *p, *p2; + int i,j; + int offset_to_next_row; + +#define SCALEBITS 10 +#define ONE_HALF (1UL << (SCALEBITS-1)) +#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5)) + + p = priv->plane[0]; + p2 = priv->plane[0] + priv->width*3; + Y = priv->Y; + Cb = priv->Cb; + Cr = priv->Cr; + offset_to_next_row = (priv->width*3*2) - 16*3; + for (i=0; i<8; i++) { + + for (j=0; j<8; j++) { + + int y, cb, cr; + int add_r, add_g, add_b; + int r, g , b; + + cb = *Cb++ - 128; + cr = *Cr++ - 128; + add_r = FIX(1.40200) * cr + ONE_HALF; + add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; + add_b = FIX(1.77200) * cb + ONE_HALF; + + y = (*Y++) << SCALEBITS; + b = (y + add_b) >> SCALEBITS; + *p++ = clamp(b); + g = (y + add_g) >> SCALEBITS; + *p++ = clamp(g); + r = (y + add_r) >> SCALEBITS; + *p++ = clamp(r); + + y = (*Y++) << SCALEBITS; + b = (y + add_b) >> SCALEBITS; + *p++ = clamp(b); + g = (y + add_g) >> SCALEBITS; + *p++ = clamp(g); + r = (y + add_r) >> SCALEBITS; + *p++ = clamp(r); + + y = (Y[16-2]) << SCALEBITS; + b = (y + add_b) >> SCALEBITS; + *p2++ = clamp(b); + g = (y + add_g) >> SCALEBITS; + *p2++ = clamp(g); + r = (y + add_r) >> SCALEBITS; + *p2++ = clamp(r); + + y = (Y[16-1]) << SCALEBITS; + b = (y + add_b) >> SCALEBITS; + *p2++ = clamp(b); + g = (y + add_g) >> SCALEBITS; + *p2++ = clamp(g); + r = (y + add_r) >> SCALEBITS; + *p2++ = clamp(r); + } + Y += 16; + p += offset_to_next_row; + p2 += offset_to_next_row; + } + +#undef SCALEBITS +#undef ONE_HALF +#undef FIX + +} + + + +/** + * YCrCb -> Grey (1x1) + * .---. + * | 1 | + * `---' + */ +static void YCrCB_to_Grey_1x1(struct jdec_private *priv) +{ + const unsigned char *y; + unsigned char *p; + unsigned int i; + int offset_to_next_row; + + p = priv->plane[0]; + y = priv->Y; + offset_to_next_row = priv->width; + + for (i=0; i<8; i++) { + memcpy(p, y, 8); + y+=8; + p += offset_to_next_row; + } +} + +/** + * YCrCb -> Grey (2x1) + * .-------. + * | 1 | 2 | + * `-------' + */ +static void YCrCB_to_Grey_2x1(struct jdec_private *priv) +{ + const unsigned char *y; + unsigned char *p; + unsigned int i; + + p = priv->plane[0]; + y = priv->Y; + + for (i=0; i<8; i++) { + memcpy(p, y, 16); + y += 16; + p += priv->width; + } +} + + +/** + * YCrCb -> Grey (1x2) + * .---. + * | 1 | + * |---| + * | 2 | + * `---' + */ +static void YCrCB_to_Grey_1x2(struct jdec_private *priv) +{ + const unsigned char *y; + unsigned char *p; + unsigned int i; + + p = priv->plane[0]; + y = priv->Y; + + for (i=0; i<16; i++) { + memcpy(p, y, 8); + y += 8; + p += priv->width; + } +} + +/** + * YCrCb -> Grey (2x2) + * .-------. + * | 1 | 2 | + * |---+---| + * | 3 | 4 | + * `-------' + */ +static void YCrCB_to_Grey_2x2(struct jdec_private *priv) +{ + const unsigned char *y; + unsigned char *p; + unsigned int i; + + p = priv->plane[0]; + y = priv->Y; + + for (i=0; i<16; i++) { + memcpy(p, y, 16); + y += 16; + p += priv->width; + } +} + + +/* + * Decode all the 3 components for 1x1 + */ +static void decode_MCU_1x1_3planes(struct jdec_private *priv) +{ + // Y + process_Huffman_data_unit(priv, cY); + IDCT(&priv->component_infos[cY], priv->Y, 8); + + // Cb + process_Huffman_data_unit(priv, cCb); + IDCT(&priv->component_infos[cCb], priv->Cb, 8); + + // Cr + process_Huffman_data_unit(priv, cCr); + IDCT(&priv->component_infos[cCr], priv->Cr, 8); +} + +/* + * Decode a 1x1 directly in 1 color + */ +static void decode_MCU_1x1_1plane(struct jdec_private *priv) +{ + // Y + process_Huffman_data_unit(priv, cY); + IDCT(&priv->component_infos[cY], priv->Y, 8); + + // Cb + process_Huffman_data_unit(priv, cCb); + IDCT(&priv->component_infos[cCb], priv->Cb, 8); + + // Cr + process_Huffman_data_unit(priv, cCr); + IDCT(&priv->component_infos[cCr], priv->Cr, 8); +} + + +/* + * Decode a 2x1 + * .-------. + * | 1 | 2 | + * `-------' + */ +static void decode_MCU_2x1_3planes(struct jdec_private *priv) +{ + // Y + process_Huffman_data_unit(priv, cY); + IDCT(&priv->component_infos[cY], priv->Y, 16); + process_Huffman_data_unit(priv, cY); + IDCT(&priv->component_infos[cY], priv->Y+8, 16); + + // Cb + process_Huffman_data_unit(priv, cCb); + IDCT(&priv->component_infos[cCb], priv->Cb, 8); + + // Cr + process_Huffman_data_unit(priv, cCr); + IDCT(&priv->component_infos[cCr], priv->Cr, 8); +} + +/* + * Decode a 2x1 + * .-------. + * | 1 | 2 | + * `-------' + */ +static void decode_MCU_2x1_1plane(struct jdec_private *priv) +{ + // Y + process_Huffman_data_unit(priv, cY); + IDCT(&priv->component_infos[cY], priv->Y, 16); + process_Huffman_data_unit(priv, cY); + IDCT(&priv->component_infos[cY], priv->Y+8, 16); + + // Cb + process_Huffman_data_unit(priv, cCb); + + // Cr + process_Huffman_data_unit(priv, cCr); +} + + +/* + * Decode a 2x2 + * .-------. + * | 1 | 2 | + * |---+---| + * | 3 | 4 | + * `-------' + */ +static void decode_MCU_2x2_3planes(struct jdec_private *priv) +{ + // Y + process_Huffman_data_unit(priv, cY); + IDCT(&priv->component_infos[cY], priv->Y, 16); + process_Huffman_data_unit(priv, cY); + IDCT(&priv->component_infos[cY], priv->Y+8, 16); + process_Huffman_data_unit(priv, cY); + IDCT(&priv->component_infos[cY], priv->Y+64*2, 16); + process_Huffman_data_unit(priv, cY); + IDCT(&priv->component_infos[cY], priv->Y+64*2+8, 16); + + // Cb + process_Huffman_data_unit(priv, cCb); + IDCT(&priv->component_infos[cCb], priv->Cb, 8); + + // Cr + process_Huffman_data_unit(priv, cCr); + IDCT(&priv->component_infos[cCr], priv->Cr, 8); +} + +/* + * Decode a 2x2 directly in GREY format (8bits) + * .-------. + * | 1 | 2 | + * |---+---| + * | 3 | 4 | + * `-------' + */ +static void decode_MCU_2x2_1plane(struct jdec_private *priv) +{ + // Y + process_Huffman_data_unit(priv, cY); + IDCT(&priv->component_infos[cY], priv->Y, 16); + process_Huffman_data_unit(priv, cY); + IDCT(&priv->component_infos[cY], priv->Y+8, 16); + process_Huffman_data_unit(priv, cY); + IDCT(&priv->component_infos[cY], priv->Y+64*2, 16); + process_Huffman_data_unit(priv, cY); + IDCT(&priv->component_infos[cY], priv->Y+64*2+8, 16); + + // Cb + process_Huffman_data_unit(priv, cCb); + + // Cr + process_Huffman_data_unit(priv, cCr); +} + +/* + * Decode a 1x2 mcu + * .---. + * | 1 | + * |---| + * | 2 | + * `---' + */ +static void decode_MCU_1x2_3planes(struct jdec_private *priv) +{ + // Y + process_Huffman_data_unit(priv, cY); + IDCT(&priv->component_infos[cY], priv->Y, 8); + process_Huffman_data_unit(priv, cY); + IDCT(&priv->component_infos[cY], priv->Y+64, 8); + + // Cb + process_Huffman_data_unit(priv, cCb); + IDCT(&priv->component_infos[cCb], priv->Cb, 8); + + // Cr + process_Huffman_data_unit(priv, cCr); + IDCT(&priv->component_infos[cCr], priv->Cr, 8); +} + +/* + * Decode a 1x2 mcu + * .---. + * | 1 | + * |---| + * | 2 | + * `---' + */ +static void decode_MCU_1x2_1plane(struct jdec_private *priv) +{ + // Y + process_Huffman_data_unit(priv, cY); + IDCT(&priv->component_infos[cY], priv->Y, 8); + process_Huffman_data_unit(priv, cY); + IDCT(&priv->component_infos[cY], priv->Y+64, 8); + + // Cb + process_Huffman_data_unit(priv, cCb); + + // Cr + process_Huffman_data_unit(priv, cCr); +} + +static void print_SOF(const unsigned char *stream) +{ + int width, height, nr_components, precision; +#if DEBUG + const char *nr_components_to_string[] = { + "????", + "Grayscale", + "????", + "YCbCr", + "CYMK" + }; +#endif + + precision = stream[2]; + height = be16_to_cpu(stream+3); + width = be16_to_cpu(stream+5); + nr_components = stream[7]; + + trace("> SOF marker\n"); + trace("Size:%dx%d nr_components:%d (%s) precision:%d\n", + width, height, + nr_components, nr_components_to_string[nr_components], + precision); +} + +/******************************************************************************* + * + * JPEG/JFIF Parsing functions + * + * Note: only a small subset of the jpeg file format is supported. No markers, + * nor progressive stream is supported. + * + ******************************************************************************/ + +static void build_quantization_table(float *qtable, const unsigned char *ref_table) +{ + /* Taken from libjpeg. Copyright Independent JPEG Group's LLM idct. + * For float AA&N IDCT method, divisors are equal to quantization + * coefficients scaled by scalefactor[row]*scalefactor[col], where + * scalefactor[0] = 1 + * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 + * We apply a further scale factor of 8. + * What's actually stored is 1/divisor so that the inner loop can + * use a multiplication rather than a division. + */ + int i, j; + static const double aanscalefactor[8] = { + 1.0, 1.387039845, 1.306562965, 1.175875602, + 1.0, 0.785694958, 0.541196100, 0.275899379 + }; + const unsigned char *zz = zigzag; + + for (i=0; i<8; i++) { + for (j=0; j<8; j++) { + *qtable++ = ref_table[*zz++] * aanscalefactor[i] * aanscalefactor[j]; + } + } + +} + +static int parse_DQT(struct jdec_private *priv, const unsigned char *stream) +{ + int qi; + float *table; + const unsigned char *dqt_block_end; + + trace("> DQT marker\n"); + dqt_block_end = stream + be16_to_cpu(stream); + stream += 2; /* Skip length */ + + while (stream < dqt_block_end) + { + qi = *stream++; +#if SANITY_CHECK + if (qi>>4) + error("16 bits quantization table is not supported\n"); + if (qi>4) + error("No more 4 quantization table is supported (got %d)\n", qi); +#endif + table = priv->Q_tables[qi]; + build_quantization_table(table, stream); + stream += 64; + } + trace("< DQT marker\n"); + return 0; +} + +static int parse_SOF(struct jdec_private *priv, const unsigned char *stream) +{ + int i, width, height, nr_components, cid, sampling_factor; + int Q_table; + struct component *c; + + trace("> SOF marker\n"); + print_SOF(stream); + + height = be16_to_cpu(stream+3); + width = be16_to_cpu(stream+5); + nr_components = stream[7]; +#if SANITY_CHECK + if (stream[2] != 8) + error("Precision other than 8 is not supported\n"); + if (width>JPEG_MAX_WIDTH || height>JPEG_MAX_HEIGHT) + error("Width and Height (%dx%d) seems suspicious\n", width, height); + if (nr_components != 3) + error("We only support YUV images\n"); + if (height%8) + error("Height need to be a multiple of 8 (current height is %d)\n", height); + if (width%16) + error("Width need to be a multiple of 16 (current Width is %d)\n", width); +#endif + stream += 8; + for (i=0; i<nr_components; i++) { + cid = *stream++; + sampling_factor = *stream++; + Q_table = *stream++; + c = &priv->component_infos[i]; +#if SANITY_CHECK + c->cid = cid; +#endif + c->Vfactor = sampling_factor&0xf; + c->Hfactor = sampling_factor>>4; + c->Q_table = priv->Q_tables[Q_table]; + trace("Component:%d factor:%dx%d Quantization table:%d\n", + cid, c->Hfactor, c->Hfactor, Q_table ); + + } + priv->width = width; + priv->height = height; + + trace("< SOF marker\n"); + + return 0; +} + +static int parse_SOS(struct jdec_private *priv, const unsigned char *stream) +{ + unsigned int i, cid, table; + unsigned int nr_components = stream[2]; + + trace("> SOS marker\n"); + +#if SANITY_CHECK + if (nr_components != 3) + error("We only support YCbCr image\n"); +#endif + + stream += 3; + for (i=0;i<nr_components;i++) { + cid = *stream++; + table = *stream++; +#if SANITY_CHECK + if ((table&0xf)>=4) + error("We do not support more than 2 AC Huffman table\n"); + if ((table>>4)>=4) + error("We do not support more than 2 DC Huffman table\n"); + if (cid != priv->component_infos[i].cid) + error("SOS cid order (%d:%d) isn't compatible with the SOF marker (%d:%d)\n", + i, cid, i, priv->component_infos[i].cid); + trace("ComponentId:%d tableAC:%d tableDC:%d\n", cid, table&0xf, table>>4); +#endif + priv->component_infos[i].AC_table = &priv->HTAC[table&0xf]; + priv->component_infos[i].DC_table = &priv->HTDC[table>>4]; + } + priv->stream = stream+3; + + /* ITU-T T.81 (9/92) chapter E.1.3 clearly states that RSTm is to be set to 0 at the beginning of each scan */ + priv->last_rst_marker_seen = 0; + + trace("< SOS marker\n"); + + return 0; +} + +static int parse_DHT(struct jdec_private *priv, const unsigned char *stream) +{ + unsigned int count, i; + unsigned char huff_bits[17]; + int length, index; + + length = be16_to_cpu(stream) - 2; + stream += 2; /* Skip length */ + + trace("> DHT marker (length=%d)\n", length); + + while (length>0) { + index = *stream++; + + /* We need to calculate the number of bytes 'vals' will takes */ + huff_bits[0] = 0; + count = 0; + for (i=1; i<17; i++) { + huff_bits[i] = *stream++; + count += huff_bits[i]; + } +#if SANITY_CHECK + if (count > 1024) + error("No more than 1024 bytes is allowed to describe a huffman table"); + if ( (index &0xf) >= HUFFMAN_TABLES) + error("No mode than %d Huffman tables is supported\n", HUFFMAN_TABLES); + trace("Huffman table %s n%d\n", (index&0xf0)?"AC":"DC", index&0xf); + trace("Length of the table: %d\n", count); +#endif + + if (index & 0xf0 ) + build_huffman_table(huff_bits, stream, &priv->HTAC[index&0xf]); + else + build_huffman_table(huff_bits, stream, &priv->HTDC[index&0xf]); + + length -= 1; + length -= 16; + length -= count; + stream += count; + } + trace("< DHT marker\n"); + return 0; +} + +static int parse_DRI(struct jdec_private *priv, const unsigned char *stream) +{ + unsigned int length; + + trace("> DRI marker\n"); + + length = be16_to_cpu(stream); + +#if SANITY_CHECK + if (length != 4) + error("Length of DRI marker need to be 4\n"); +#endif + + priv->restart_interval = be16_to_cpu(stream+2); + +#if DEBUG + trace("Restart interval = %d\n", priv->restart_interval); +#endif + + trace("< DRI marker\n"); + + return 0; +} + + + +static void resync(struct jdec_private *priv) +{ + int i; + + /* Init DC coefficients */ + for (i=0; i<COMPONENTS; i++) + priv->component_infos[i].previous_DC = 0; + + priv->reservoir = 0; + priv->nbits_in_reservoir = 0; + if (priv->restart_interval > 0) + priv->restarts_to_go = priv->restart_interval; + else + priv->restarts_to_go = -1; +} + +static int find_next_rst_marker(struct jdec_private *priv) +{ + int rst_marker_found = 0; + int marker; + const unsigned char *stream = priv->stream; + + /* Parse marker */ + while (!rst_marker_found) + { + while (*stream++ != 0xff) + { + if (stream >= priv->stream_end) + error("EOF while search for a RST marker."); + } + /* Skip any padding ff byte (this is normal) */ + while (*stream == 0xff) + stream++; + + marker = *stream++; + if ((RST+priv->last_rst_marker_seen) == marker) + rst_marker_found = 1; + else if (marker >= RST && marker <= RST7) + error("Wrong Reset marker found, abording"); + else if (marker == EOI) + return 0; + } + + priv->stream = stream; + priv->last_rst_marker_seen++; + priv->last_rst_marker_seen &= 7; + + return 0; +} + +static int parse_JFIF(struct jdec_private *priv, const unsigned char *stream) +{ + int chuck_len; + int marker; + int sos_marker_found = 0; + int dht_marker_found = 0; + const unsigned char *next_chunck; + + /* Parse marker */ + while (!sos_marker_found) + { + if (*stream++ != 0xff) + goto bogus_jpeg_format; + /* Skip any padding ff byte (this is normal) */ + while (*stream == 0xff) + stream++; + + marker = *stream++; + chuck_len = be16_to_cpu(stream); + next_chunck = stream + chuck_len; + switch (marker) + { + case SOF: + if (parse_SOF(priv, stream) < 0) + return -1; + break; + case DQT: + if (parse_DQT(priv, stream) < 0) + return -1; + break; + case SOS: + if (parse_SOS(priv, stream) < 0) + return -1; + sos_marker_found = 1; + break; + case DHT: + if (parse_DHT(priv, stream) < 0) + return -1; + dht_marker_found = 1; + break; + case DRI: + if (parse_DRI(priv, stream) < 0) + return -1; + break; + default: + trace("> Unknown marker %2.2x\n", marker); + break; + } + + stream = next_chunck; + } + + if (!dht_marker_found) { + trace("No Huffman table loaded, using the default one\n"); + build_default_huffman_tables(priv); + } + +#ifdef SANITY_CHECK + if ( (priv->component_infos[cY].Hfactor < priv->component_infos[cCb].Hfactor) + || (priv->component_infos[cY].Hfactor < priv->component_infos[cCr].Hfactor)) + error("Horizontal sampling factor for Y should be greater than horitontal sampling factor for Cb or Cr\n"); + if ( (priv->component_infos[cY].Vfactor < priv->component_infos[cCb].Vfactor) + || (priv->component_infos[cY].Vfactor < priv->component_infos[cCr].Vfactor)) + error("Vertical sampling factor for Y should be greater than vertical sampling factor for Cb or Cr\n"); + if ( (priv->component_infos[cCb].Hfactor!=1) + || (priv->component_infos[cCr].Hfactor!=1) + || (priv->component_infos[cCb].Vfactor!=1) + || (priv->component_infos[cCr].Vfactor!=1)) + error("Sampling other than 1x1 for Cr and Cb is not supported"); +#endif + + return 0; +bogus_jpeg_format: + error("Bogus jpeg format\n"); + return -1; +} + +/******************************************************************************* + * + * Functions exported of the library. + * + * Note: Some applications can access directly to internal pointer of the + * structure. It's is not recommended, but if you have many images to + * uncompress with the same parameters, some functions can be called to speedup + * the decoding. + * + ******************************************************************************/ + +/** + * Allocate a new tinyjpeg decoder object. + * + * Before calling any other functions, an object need to be called. + */ +struct jdec_private *tinyjpeg_init(void) +{ + struct jdec_private *priv; + + priv = (struct jdec_private *)calloc(1, sizeof(struct jdec_private)); + if (priv == NULL) + return NULL; + return priv; +} + +/** + * Free a tinyjpeg object. + * + * No others function can be called after this one. + */ +void tinyjpeg_free(struct jdec_private *priv) +{ + int i; + for (i=0; i<COMPONENTS; i++) { + if (priv->components[i]) + free(priv->components[i]); + priv->components[i] = NULL; + } + free(priv); +} + +/** + * Initialize the tinyjpeg object and prepare the decoding of the stream. + * + * Check if the jpeg can be decoded with this jpeg decoder. + * Fill some table used for preprocessing. + */ +int tinyjpeg_parse_header(struct jdec_private *priv, const unsigned char *buf, unsigned int size) +{ + int ret; + + /* Identify the file */ + if ((buf[0] != 0xFF) || (buf[1] != SOI)) + error("Not a JPG file ?\n"); + + priv->stream_begin = buf+2; + priv->stream_length = size-2; + priv->stream_end = priv->stream_begin + priv->stream_length; + + ret = parse_JFIF(priv, priv->stream_begin); + + return ret; +} + +static const decode_MCU_fct decode_mcu_3comp_table[4] = { + decode_MCU_1x1_3planes, + decode_MCU_1x2_3planes, + decode_MCU_2x1_3planes, + decode_MCU_2x2_3planes, +}; + +static const decode_MCU_fct decode_mcu_1comp_table[4] = { + decode_MCU_1x1_1plane, + decode_MCU_1x2_1plane, + decode_MCU_2x1_1plane, + decode_MCU_2x2_1plane, +}; + +static const convert_colorspace_fct convert_colorspace_yuv420p[4] = { + YCrCB_to_YUV420P_1x1, + YCrCB_to_YUV420P_1x2, + YCrCB_to_YUV420P_2x1, + YCrCB_to_YUV420P_2x2, +}; + +static const convert_colorspace_fct convert_colorspace_rgb24[4] = { + YCrCB_to_RGB24_1x1, + YCrCB_to_RGB24_1x2, + YCrCB_to_RGB24_2x1, + YCrCB_to_RGB24_2x2, +}; + +static const convert_colorspace_fct convert_colorspace_bgr24[4] = { + YCrCB_to_BGR24_1x1, + YCrCB_to_BGR24_1x2, + YCrCB_to_BGR24_2x1, + YCrCB_to_BGR24_2x2, +}; + +static const convert_colorspace_fct convert_colorspace_grey[4] = { + YCrCB_to_Grey_1x1, + YCrCB_to_Grey_1x2, + YCrCB_to_Grey_2x1, + YCrCB_to_Grey_2x2, +}; + +/** + * Decode and convert the jpeg image into @pixfmt@ image + * + * Note: components will be automaticaly allocated if no memory is attached. + */ +int tinyjpeg_decode(struct jdec_private *priv, int pixfmt) +{ + unsigned int x, y, xstride_by_mcu, ystride_by_mcu; + unsigned int bytes_per_blocklines[3], bytes_per_mcu[3]; + decode_MCU_fct decode_MCU; + const decode_MCU_fct *decode_mcu_table; + const convert_colorspace_fct *colorspace_array_conv; + convert_colorspace_fct convert_to_pixfmt; + + if (setjmp(priv->jump_state)) + return -1; + + /* To keep gcc happy initialize some array */ + bytes_per_mcu[1] = 0; + bytes_per_mcu[2] = 0; + bytes_per_blocklines[1] = 0; + bytes_per_blocklines[2] = 0; + + decode_mcu_table = decode_mcu_3comp_table; + switch (pixfmt) { + case TINYJPEG_FMT_YUV420P: + colorspace_array_conv = convert_colorspace_yuv420p; + if (priv->components[0] == NULL) + priv->components[0] = (uint8_t *)malloc(priv->width * priv->height); + if (priv->components[1] == NULL) + priv->components[1] = (uint8_t *)malloc(priv->width * priv->height/4); + if (priv->components[2] == NULL) + priv->components[2] = (uint8_t *)malloc(priv->width * priv->height/4); + bytes_per_blocklines[0] = priv->width; + bytes_per_blocklines[1] = priv->width/4; + bytes_per_blocklines[2] = priv->width/4; + bytes_per_mcu[0] = 8; + bytes_per_mcu[1] = 4; + bytes_per_mcu[2] = 4; + break; + + case TINYJPEG_FMT_RGB24: + colorspace_array_conv = convert_colorspace_rgb24; + if (priv->components[0] == NULL) + priv->components[0] = (uint8_t *)malloc(priv->width * priv->height * 3); + bytes_per_blocklines[0] = priv->width * 3; + bytes_per_mcu[0] = 3*8; + break; + + case TINYJPEG_FMT_BGR24: + colorspace_array_conv = convert_colorspace_bgr24; + if (priv->components[0] == NULL) + priv->components[0] = (uint8_t *)malloc(priv->width * priv->height * 3); + bytes_per_blocklines[0] = priv->width * 3; + bytes_per_mcu[0] = 3*8; + break; + + case TINYJPEG_FMT_GREY: + decode_mcu_table = decode_mcu_1comp_table; + colorspace_array_conv = convert_colorspace_grey; + if (priv->components[0] == NULL) + priv->components[0] = (uint8_t *)malloc(priv->width * priv->height); + bytes_per_blocklines[0] = priv->width; + bytes_per_mcu[0] = 8; + break; + + default: + trace("Bad pixel format\n"); + return -1; + } + + xstride_by_mcu = ystride_by_mcu = 8; + if ((priv->component_infos[cY].Hfactor | priv->component_infos[cY].Vfactor) == 1) { + decode_MCU = decode_mcu_table[0]; + convert_to_pixfmt = colorspace_array_conv[0]; + trace("Use decode 1x1 sampling\n"); + } else if (priv->component_infos[cY].Hfactor == 1) { + decode_MCU = decode_mcu_table[1]; + convert_to_pixfmt = colorspace_array_conv[1]; + ystride_by_mcu = 16; + trace("Use decode 1x2 sampling (not supported)\n"); + } else if (priv->component_infos[cY].Vfactor == 2) { + decode_MCU = decode_mcu_table[3]; + convert_to_pixfmt = colorspace_array_conv[3]; + xstride_by_mcu = 16; + ystride_by_mcu = 16; + trace("Use decode 2x2 sampling\n"); + } else { + decode_MCU = decode_mcu_table[2]; + convert_to_pixfmt = colorspace_array_conv[2]; + xstride_by_mcu = 16; + trace("Use decode 2x1 sampling\n"); + } + + resync(priv); + + /* Don't forget to that block can be either 8 or 16 lines */ + bytes_per_blocklines[0] *= ystride_by_mcu; + bytes_per_blocklines[1] *= ystride_by_mcu; + bytes_per_blocklines[2] *= ystride_by_mcu; + + bytes_per_mcu[0] *= xstride_by_mcu/8; + bytes_per_mcu[1] *= xstride_by_mcu/8; + bytes_per_mcu[2] *= xstride_by_mcu/8; + + /* Just the decode the image by macroblock (size is 8x8, 8x16, or 16x16) */ + for (y=0; y < priv->height/ystride_by_mcu; y++) + { + //trace("Decoding row %d\n", y); + priv->plane[0] = priv->components[0] + (y * bytes_per_blocklines[0]); + priv->plane[1] = priv->components[1] + (y * bytes_per_blocklines[1]); + priv->plane[2] = priv->components[2] + (y * bytes_per_blocklines[2]); + for (x=0; x < priv->width; x+=xstride_by_mcu) + { + decode_MCU(priv); + convert_to_pixfmt(priv); + priv->plane[0] += bytes_per_mcu[0]; + priv->plane[1] += bytes_per_mcu[1]; + priv->plane[2] += bytes_per_mcu[2]; + if (priv->restarts_to_go>0) + { + priv->restarts_to_go--; + if (priv->restarts_to_go == 0) + { + priv->stream -= (priv->nbits_in_reservoir/8); + resync(priv); + if (find_next_rst_marker(priv) < 0) + return -1; + } + } + } + } + + return 0; +} + +const char *tinyjpeg_get_errorstring(struct jdec_private *priv) +{ + return priv->error_string; +} + +void tinyjpeg_get_size(struct jdec_private *priv, unsigned int *width, unsigned int *height) +{ + *width = priv->width; + *height = priv->height; +} + +int tinyjpeg_get_components(struct jdec_private *priv, unsigned char **components) +{ + int i; + for (i=0; priv->components[i] && i<COMPONENTS; i++) + components[i] = priv->components[i]; + return 0; +} + +int tinyjpeg_set_components(struct jdec_private *priv, unsigned char **components, unsigned int ncomponents) +{ + unsigned int i; + if (ncomponents > COMPONENTS) + ncomponents = COMPONENTS; + for (i=0; i<ncomponents; i++) + priv->components[i] = components[i]; + return 0; +} + +int tinyjpeg_set_flags(struct jdec_private *priv, int flags) +{ + int oldflags = priv->flags; + priv->flags = flags; + return oldflags; +} + diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/tinyjpeg.h b/v4l2-apps/lib/libv4l/libv4lconvert/tinyjpeg.h new file mode 100644 index 000000000..42b60c1ee --- /dev/null +++ b/v4l2-apps/lib/libv4l/libv4lconvert/tinyjpeg.h @@ -0,0 +1,73 @@ +/* + * Small jpeg decoder library (header file) + * + * Copyright (c) 2006, Luc Saillard <luc@saillard.org> + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * - Neither the name of the author nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef __JPEGDEC_H__ +#define __JPEGDEC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +struct jdec_private; + +/* Flags that can be set by any applications */ +#define TINYJPEG_FLAGS_MJPEG_TABLE (1<<1) + +/* Format accepted in outout */ +enum tinyjpeg_fmt { + TINYJPEG_FMT_GREY = 1, + TINYJPEG_FMT_BGR24, + TINYJPEG_FMT_RGB24, + TINYJPEG_FMT_YUV420P, +}; + +struct jdec_private *tinyjpeg_init(void); +void tinyjpeg_free(struct jdec_private *priv); + +int tinyjpeg_parse_header(struct jdec_private *priv, const unsigned char *buf, unsigned int size); +int tinyjpeg_decode(struct jdec_private *priv, int pixel_format); +const char *tinyjpeg_get_errorstring(struct jdec_private *priv); +void tinyjpeg_get_size(struct jdec_private *priv, unsigned int *width, unsigned int *height); +int tinyjpeg_get_components(struct jdec_private *priv, unsigned char **components); +int tinyjpeg_set_components(struct jdec_private *priv, unsigned char **components, unsigned int ncomponents); +int tinyjpeg_set_flags(struct jdec_private *priv, int flags); + +#ifdef __cplusplus +} +#endif + +#endif + + + diff --git a/v4l_experimental/dpl3518.c b/v4l_experimental/dpl3518.c index 43533767e..a9ee6bd52 100644 --- a/v4l_experimental/dpl3518.c +++ b/v4l_experimental/dpl3518.c @@ -46,12 +46,7 @@ #include <linux/fs.h> #include <asm/uaccess.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include "id.h" -#include "i2c-compat.h" -#else #include <media/id.h> -#endif #include "dpl3518.h" @@ -60,9 +55,7 @@ static unsigned short normal_i2c[] = { I2C_DPL3518 >> 1, I2C_CLIENT_END}; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -static unsigned short normal_i2c_range[] = {I2C_CLIENT_END}; -#endif + I2C_CLIENT_INSMOD; struct dpl3518 { @@ -235,12 +228,7 @@ static void dpl3518_spatial(struct i2c_client *client, int spatial) /* ----------------------------------------------------------------------- */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) static int dpl3518_attach(struct i2c_adapter *adap, int addr, int kind) -#else -static int dpl3518_attach(struct i2c_adapter *adap, int addr, - unsigned short flags, int kind) -#endif { struct dpl3518 *dpl; struct i2c_client *client; @@ -365,9 +353,7 @@ static int dpl3518_dev_release(struct inode *inode, struct file *file) /* ---------------------------------------------------------------------- */ static struct i2c_driver driver = { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,54) .owner = THIS_MODULE, -#endif .name = "i2c dpl3518 driver", .id = I2C_DRIVERID_DPL3518, .flags = I2C_DF_NOTIFY, diff --git a/v4l_experimental/v3tv/v3tv.c b/v4l_experimental/v3tv/v3tv.c index 6f105cb3b..9029fa733 100644 --- a/v4l_experimental/v3tv/v3tv.c +++ b/v4l_experimental/v3tv/v3tv.c @@ -17,14 +17,8 @@ #include <asm/io.h> #include <asm/pgtable.h> -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) #include <media/tuner.h> #include <media/audiochip.h> -#else -#include "/usr/src/linux/drivers/media/video/i2c-compat.h" -#include "/usr/src/linux/drivers/media/video/audiochip.h" -#include "/usr/src/linux/drivers/media/video/tuner.h" -#endif //#ifndef I2C_DRIVERID_VPX3224 //#include "vpx-common.h" @@ -32,9 +26,6 @@ //#include <linux/i2c.h> -//#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -//#include "../linux/drivers/media/video/i2c-compat.h" -//#endif #define UNSET (-1U) @@ -549,12 +540,8 @@ static inline unsigned long uvirt_to_kva(pgd_t * pgd, unsigned long adr) #endif #endif if (pte_present(pte)) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) ret = (unsigned long)page_address(pte_page(pte)); -#else - ret = pte_page(pte); -#endif ret |= (adr & (PAGE_SIZE - 1)); } } @@ -601,12 +588,8 @@ inline unsigned long kvirt_to_pa(unsigned long adr) return ret; } -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0) -#include <linux/wrapper.h> -#else #define mem_map_reserve(p) set_bit(PG_reserved, &((p)->flags)) #define mem_map_unreserve(p) clear_bit(PG_reserved, &((p)->flags)) -#endif void inline *rvmalloc(signed long size) { @@ -731,20 +714,8 @@ int v3tv_get_adapter(struct i2c_adapter *adapter) if (debug) printk(KERN_INFO "v3tv: v3tv_get_adapter trying: %s\n", adapter->name); -// if (I2C_CLASS_TV_ANALOG != adapter->class) -// return 0; -#ifdef I2C_CLASS_TV_ANALOG if (!(adapter->class & I2C_CLASS_TV_ANALOG)) return 0; -#else - switch (adapter->id) { - case I2C_ALGO_BIT | I2C_HW_B_VOO: - if (!strnicmp(adapter->name, "I2C\0", 3)) - break; - default: - return 0; - } -#endif if (debug) printk(KERN_INFO "v3tv: i2c_attach_client found adapter: %s\n", adapter->name); @@ -753,25 +724,17 @@ int v3tv_get_adapter(struct i2c_adapter *adapter) if (debug) printk(KERN_INFO "v3tv: i2c_attach_client releasing adapter: %s\n", adapter->name); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) module_put(voodoo->voodoo_i2c_adapter->owner); -#else - __MOD_DEC_USE_COUNT(voodoo->voodoo_i2c_adapter->owner); -#endif voodoo->voodoo_i2c_adapter = NULL; return 0; } voodoo->voodoo_i2c_adapter = adapter; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) if (!try_module_get(adapter->owner)) { printk("v3tv: Unable to get module %s\n", adapter->owner->name); return -ENODEV; } -#else - __MOD_INC_USE_COUNT(voodoo->voodoo_i2c_adapter->owner); -#endif printk ("v3tv: i2c dummy driver registered: adapter: 0x%p\n", voodoo->voodoo_i2c_adapter); @@ -1402,10 +1365,6 @@ static int do_voodoo_mmap(const char *adr, unsigned long size) * $Id: v3tv.c,v 1.1 2005/12/25 16:23:58 mkrufky Exp $ */ -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0) -#define iminor(inode) minor(inode->i_rdev) -#endif - /* External variables: Data struct */ //extern struct voodoo_data *voodoo; //extern struct video_capture video_standard[]; @@ -2034,11 +1993,7 @@ static int v3tv_radio_open(struct inode *inode, struct file *file) AUDC_SET_RADIO, &voodoo->tuner_type); // up(&voodoo->lock); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) try_module_get(THIS_MODULE); -#else - MOD_INC_USE_COUNT; -#endif printk("v3tv: Radio device opened.\n"); return 0; } @@ -2053,11 +2008,7 @@ static int v3tv_radio_release(struct inode *inode, struct file *file) file->private_data = NULL; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) module_put(THIS_MODULE); -#else - MOD_DEC_USE_COUNT; -#endif printk("v3tv: Radio device closed.\n"); @@ -2182,11 +2133,7 @@ static irqreturn_t v3tv_video_irq(int irq, void *dev_id, struct pt_regs *regs) tempReg |= (1 << 31); v3tv_regwrite(V3REG_intrCtrl, tempReg); } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) return capture_ready; -#else - return; -#endif } void v3tv_set_palette(struct video_picture *picture_settings) diff --git a/v4l_experimental/v3tv/vpx3224.c b/v4l_experimental/v3tv/vpx3224.c index fb5f05b79..50c60ca53 100644 --- a/v4l_experimental/v3tv/vpx3224.c +++ b/v4l_experimental/v3tv/vpx3224.c @@ -45,9 +45,6 @@ #include <linux/i2c.h> #include <linux/i2c-dev.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -#include "i2c-compat.h" -#endif #include <linux/videodev.h> #include <linux/video_decoder.h> @@ -67,11 +64,9 @@ static int vpx3224_write_fp_block(struct i2c_client *client, const u16 * data, int len); #endif + static int vpx3224_detect_client(struct i2c_adapter *adapter, int address, -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - unsigned short flags, -#endif - int kind); + int kind); /* Each client has this additional data */ @@ -606,12 +601,6 @@ vpx3224_write_fp_block(struct i2c_client *client, return res; } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -#if defined (CONFIG_V3TV_VERBOSEDEBUG) & defined (CONFIG_PROC_FS) -#include "vpx3224-proc.c" -#endif -#endif - /* ---------------------------------------------------------------------- * Client procedures */ @@ -1078,13 +1067,8 @@ static int vpx3224_attach_adapter(struct i2c_adapter *adapter) { int res = 0; -#ifdef I2C_ADAP_CLASS_TV_ANALOG - if (adapter->class & I2C_ADAP_CLASS_TV_ANALOG) - res = i2c_probe(adapter, &addr_data, vpx3224_detect_client); -#else - if (adapter->id & (I2C_HW_SMBUS_VOODOO3)) + if (adapter->class & I2C_CLASS_TV_ANALOG) res = i2c_probe(adapter, &addr_data, vpx3224_detect_client); -#endif DEB2(printk(KERN_INFO "%s: i2c_probe of adapter: %s returned %d\n", THIS_MODULE->name, adapter->name, res)); @@ -1097,11 +1081,6 @@ static int vpx3224_detach_client(struct i2c_client *client) struct vpx3224 *decoder = i2c_get_clientdata(client); int res; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -#if defined (CONFIG_PROC_FS) && defined (CONFIG_V3TV_VERBOSEDEBUG) - vpx3224_del_proc(client); -#endif -#endif res = i2c_detach_client(client); DEB2(printk(KERN_INFO "%s: i2c_detach_client returned %d\n", @@ -1111,11 +1090,7 @@ static int vpx3224_detach_client(struct i2c_client *client) THIS_MODULE->name, client->name); return res; } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -// MOD_DEC_USE_COUNT; -#else module_put(client->adapter->owner); -#endif kfree(decoder); kfree(client); vpx3224_i2c_id--; @@ -1144,9 +1119,6 @@ static struct i2c_driver vpx3224_i2c_driver = { /* vpx3224_detect_client - aka: i2c_client_found_addr_proc *found_proc * so called by i2c_probe, res passed back to vpx3224_attach_adapter */ static int vpx3224_detect_client(struct i2c_adapter *adapter, int address, -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - unsigned short flags, -#endif int kind) { int res; @@ -1230,17 +1202,7 @@ static int vpx3224_detect_client(struct i2c_adapter *adapter, int address, printk(KERN_INFO "%s: %s client found at address 0x%x\n", THIS_MODULE->name, client->name, client->addr); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -#if defined (CONFIG_PROC_FS) && defined (CONFIG_V3TV_VERBOSEDEBUG) - vpx3224_init_proc(client); -#endif -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -// MOD_INC_USE_COUNT; -#else try_module_get(client->adapter->owner); -#endif return vpx3224_i2c_id; } |