All of lore.kernel.org
 help / color / mirror / Atom feed
* DVB nGene CI : TS Discontinuities issues
@ 2011-05-03 10:59 Sébastien RAILLARD (COEXSI)
  2011-05-07 15:15 ` Issa Gorissen
  0 siblings, 1 reply; 12+ messages in thread
From: Sébastien RAILLARD (COEXSI) @ 2011-05-03 10:59 UTC (permalink / raw)
  To: Linux Media Mailing List

Dear all,

I'm doing some tests with the CI interface of the "Linux4Media cineS2 DVB-S2
Twin Tuner (v5)" card.
I notice some TS discontinuities during my tests.

My setup:
- Aston Viaccess Pro CAM
- Linux4Media cineS2 DVB-S2 Twin Tuner (v5) card
- Latest git media_build source with DF_SWAP32 patch
- DVB-S source from ASTRA 19.2E / 12285.00-V-27500

Test #1: (idle)
Reading from sec0 (without CI init or sec0 input stream) using "dd" give me
a stream of NULL TS packets of roughly 62mbps or 7.8MB/s (seems normal
behavior)
Command line: dd if=/dev/dvb/adapter14/sec0 of=/root/test.ts bs=18800
count=10000

Test #2: (CAM removal)
After CAM initialization and some tests, if CAM is removed, the output sec0
bandwidth isn't anymore 62mbps of NULL TS packets
Same command line as Test #1 is used.
It seems that the CI is badly reacting after hot remove of CAM.
After rebooting, everything is fine again.

Test #3: (Test dvr0 stream)
- Setting up the DVB-S reception: gnutv -adapter 14 -channels channels.conf
-out dvr CHAINE
- Channel configuration: CHAINE:12285:v:0:27500:170:120:17030
- Dumping the dvr0 output: dd if=/dev/dvb/adapter14/dvr0 of=/root/test.ts
bs=1880 count=1000
=> The dvr0 output bandwidth is roughly 300kB/s (normal for one filtered
channel)
=> The resulting TS file is correct (no sync missing, no continuity error)

Test #4: (Loop mode - No CAM inserted)
- Sending all TS packets from dvr0 to sec0: dd if=/dev/dvb/adapter14/dvr0
of=/dev/dvb/adapter14/sec0 bs=1880
- Setting up the DVB-S reception: gnutv -adapter 14 -channels channels.conf
-out dvr CHAINE
- Channel configuration: CHAINE:12285:v:0:27500:170:120:17030
- Dumping the sec0 output: dd if=/dev/dvb/adapter14/sec0 of=/root/test.ts
bs=18800 count=10000
=> The sec0 output bandwidth is roughly 7.8MB/s (normal as the CI output is
always 62mbps)
=> The resulting TS file is filled at 96% by NULL TS packets (normal,
regarding the input stream bandwidth of 300kB/S)
=> All the input PID seem to present in the output file
=> But, there are some discontinuities in the TS packets (a lot and for all
the PID)

Test #5: (Trough CAM - CAM is inserted)
- Sending all TS packets from dvr0 to sec0: dd if=/dev/dvb/adapter14/dvr0
of=/dev/dvb/adapter14/sec0 bs=1880
- Setting up the DVB-S reception: gnutv -adapter 14 -channels channels.conf
-out dvr CHAINE
- Channel configuration: CHAINE:12285:v:0:27500:170:120:17030
- Waiting for CAM initialization (the CAM is correctly initialized and the
PMT packet is send to the CAM)
- Dumping the sec0 output: dd if=/dev/dvb/adapter14/sec0 of=/root/test.ts
bs=18800 count=10000
=> The sec0 output bandwidth is roughly 7.8MB/s (normal as the CI output is
always 62mbps)
=> The resulting TS file is filled at 96% by NULL TS packets (normal,
regarding the input stream bandwidth of 300kB/S)
=> All the input PID seem to present in the output file
=> The stream isn't decoded (normal as the CAT table isn't outputted by
gnutv)
=> But, there are some discontinuities in the TS packets (a lot and for all
the PID)

So, in summary, I'm observing discontinues when stream is going through the
sec0 device, if CAM is present or not.
Also, the CI adapter doesn't seem to react correctly when the CAM is hot
removed.
I can provide the TS files (from dvr0, from sec0 with CAM and without CAM)
if someone is interested.

Does someone has a setup that show no discontinuities when a TS stream is
going through sec0? (with an input TS file)
I would like to test it as for me the CI interface doesn't seem to work for
the nGene cards.

Best regards,
Sebastien.








^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: DVB nGene CI : TS Discontinuities issues
  2011-05-03 10:59 DVB nGene CI : TS Discontinuities issues Sébastien RAILLARD (COEXSI)
@ 2011-05-07 15:15 ` Issa Gorissen
       [not found]   ` <19909.47855.351946.831380@morden.metzler>
  0 siblings, 1 reply; 12+ messages in thread
From: Issa Gorissen @ 2011-05-07 15:15 UTC (permalink / raw)
  To: Linux Media Mailing List
  Cc: "Sébastien RAILLARD (COEXSI)",
	Ralph Metzler, Oliver Endriss

[-- Attachment #1: Type: text/plain, Size: 4233 bytes --]

On 03/05/11 12:59, Sébastien RAILLARD (COEXSI) wrote:
> Dear all,
>
> I'm doing some tests with the CI interface of the "Linux4Media cineS2 DVB-S2
> Twin Tuner (v5)" card.
> I notice some TS discontinuities during my tests.
>
> My setup:
> - Aston Viaccess Pro CAM
> - Linux4Media cineS2 DVB-S2 Twin Tuner (v5) card
> - Latest git media_build source with DF_SWAP32 patch
> - DVB-S source from ASTRA 19.2E / 12285.00-V-27500
>
> Test #1: (idle)
> Reading from sec0 (without CI init or sec0 input stream) using "dd" give me
> a stream of NULL TS packets of roughly 62mbps or 7.8MB/s (seems normal
> behavior)
> Command line: dd if=/dev/dvb/adapter14/sec0 of=/root/test.ts bs=18800
> count=10000
>
> Test #2: (CAM removal)
> After CAM initialization and some tests, if CAM is removed, the output sec0
> bandwidth isn't anymore 62mbps of NULL TS packets
> Same command line as Test #1 is used.
> It seems that the CI is badly reacting after hot remove of CAM.
> After rebooting, everything is fine again.
>
> Test #3: (Test dvr0 stream)
> - Setting up the DVB-S reception: gnutv -adapter 14 -channels channels.conf
> -out dvr CHAINE
> - Channel configuration: CHAINE:12285:v:0:27500:170:120:17030
> - Dumping the dvr0 output: dd if=/dev/dvb/adapter14/dvr0 of=/root/test.ts
> bs=1880 count=1000
> => The dvr0 output bandwidth is roughly 300kB/s (normal for one filtered
> channel)
> => The resulting TS file is correct (no sync missing, no continuity error)
>
> Test #4: (Loop mode - No CAM inserted)
> - Sending all TS packets from dvr0 to sec0: dd if=/dev/dvb/adapter14/dvr0
> of=/dev/dvb/adapter14/sec0 bs=1880
> - Setting up the DVB-S reception: gnutv -adapter 14 -channels channels.conf
> -out dvr CHAINE
> - Channel configuration: CHAINE:12285:v:0:27500:170:120:17030
> - Dumping the sec0 output: dd if=/dev/dvb/adapter14/sec0 of=/root/test.ts
> bs=18800 count=10000
> => The sec0 output bandwidth is roughly 7.8MB/s (normal as the CI output is
> always 62mbps)
> => The resulting TS file is filled at 96% by NULL TS packets (normal,
> regarding the input stream bandwidth of 300kB/S)
> => All the input PID seem to present in the output file
> => But, there are some discontinuities in the TS packets (a lot and for all
> the PID)
>
> Test #5: (Trough CAM - CAM is inserted)
> - Sending all TS packets from dvr0 to sec0: dd if=/dev/dvb/adapter14/dvr0
> of=/dev/dvb/adapter14/sec0 bs=1880
> - Setting up the DVB-S reception: gnutv -adapter 14 -channels channels.conf
> -out dvr CHAINE
> - Channel configuration: CHAINE:12285:v:0:27500:170:120:17030
> - Waiting for CAM initialization (the CAM is correctly initialized and the
> PMT packet is send to the CAM)
> - Dumping the sec0 output: dd if=/dev/dvb/adapter14/sec0 of=/root/test.ts
> bs=18800 count=10000
> => The sec0 output bandwidth is roughly 7.8MB/s (normal as the CI output is
> always 62mbps)
> => The resulting TS file is filled at 96% by NULL TS packets (normal,
> regarding the input stream bandwidth of 300kB/S)
> => All the input PID seem to present in the output file
> => The stream isn't decoded (normal as the CAT table isn't outputted by
> gnutv)
> => But, there are some discontinuities in the TS packets (a lot and for all
> the PID)
>
> So, in summary, I'm observing discontinues when stream is going through the
> sec0 device, if CAM is present or not.
> Also, the CI adapter doesn't seem to react correctly when the CAM is hot
> removed.
> I can provide the TS files (from dvr0, from sec0 with CAM and without CAM)
> if someone is interested.
>
> Does someone has a setup that show no discontinuities when a TS stream is
> going through sec0? (with an input TS file)
> I would like to test it as for me the CI interface doesn't seem to work for
> the nGene cards.
>
> Best regards,
> Sebastien.
Ralph,

Could you please take a look at the cxd2099 issues ?

I have attached a version with my changes. I have tested a lot of
different settings with the help of the chip datasheet.

Scrambled programs are not handled correctly. I don't know if it is the
TICLK/MCLKI which is too high or something, or the sync detector ? Also,
as we have to set the TOCLK to max of 72MHz, there are way too much null
packets added. Is there a way to solve this ?

Thx
--
Issa

[-- Attachment #2: cxd2099.c --]
[-- Type: text/x-csrc, Size: 14424 bytes --]

/*
 * cxd2099.c: Driver for the CXD2099AR Common Interface Controller
 *
 * Copyright (C) 2010 DigitalDevices UG
 *
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 only, as published by the Free Software Foundation.
 *
 *
 * 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 General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA
 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
 */

#include <linux/version.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/wait.h>
#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/io.h>

#include "cxd2099.h"

static int debug;
module_param(debug, int, 0444);
MODULE_PARM_DESC(debug, "Print debugging information.");

#define dprintk if (debug) printk

struct cxd {
	struct dvb_ca_en50221 en;

	struct i2c_adapter *i2c;
	u8     adr;
//	u8     regs[0x23];
//	u8     lastaddress;
//	u8     clk_reg_f;
//	u8     clk_reg_b;
	int    mode;
//	u32    bitrate;
//	int    ready;
//	int    dr;
	int    slot_stat;

//	u8     amem[1024];
//	int    amem_read;

//	int    cammode;
	struct mutex lock;
};

static int i2c_write_reg(struct i2c_adapter *adapter, u8 adr,
			 u8 reg, u8 data)
{
	u8 m[2] = {reg, data};
	struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m, .len = 2};

	if (i2c_transfer(adapter, &msg, 1) != 1) {
		printk(KERN_ERR "cxd2099: Failed to write to I2C register %02x@%02x!\n",
		       reg, adr);
		return -1;
	}
	return 0;
}

static int i2c_write(struct i2c_adapter *adapter, u8 adr,
		     u8 *data, u8 len)
{
	struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = data, .len = len};

	if (i2c_transfer(adapter, &msg, 1) != 1) {
		printk(KERN_ERR "cxd2099: Failed to write to I2C!\n");
		return -1;
	}
	return 0;
}

static int i2c_read(struct i2c_adapter *adapter, u8 adr,
		    u8 reg, u8 *data, u8 n)
{
	struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
				   .buf = &reg, .len = 1 },
				  {.addr = adr, .flags = I2C_M_RD,
				   .buf = data, .len = n } };

	if (i2c_transfer(adapter, msgs, 2) != 2) {
		printk(KERN_ERR "cxd2099: error in i2c_read\n");
		return -1;
	}
	return 0;
}

static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr,
			u8 reg, u8 *val)
{
	return i2c_read(adapter, adr, reg, val, 1);
}

static int read_block(struct cxd *ci, u8 reg, u8 *data, u8 n)
{
	int status;

	status = i2c_write_reg(ci->i2c, ci->adr, 0, reg);
	if (!status) {
//		ci->lastaddress = adr;
		status = i2c_read(ci->i2c, ci->adr, 1, data, n);
	}
	return status;
}

static int read_reg(struct cxd *ci, u8 reg, u8 *val)
{
	return read_block(ci, reg, val, 1);
}


static int read_pccard(struct cxd *ci, u16 address, u8 *data, u8 n)
{
	int status;
	u8 addr[3] = { 2, address&0xff, address>>8 };

	status = i2c_write(ci->i2c, ci->adr, addr, 3);
	if (!status)
		status = i2c_read(ci->i2c, ci->adr, 3, data, n);
	return status;
}

static int write_pccard(struct cxd *ci, u16 address, u8 *data, u8 n)
{
	int status;
	u8 addr[3] = { 2, address&0xff, address>>8 };

	status = i2c_write(ci->i2c, ci->adr, addr, 3);
	if (!status) {
		u8 buf[256] = {3};
		memcpy(buf+1, data, n);
		status = i2c_write(ci->i2c, ci->adr, buf, n+1);
	}
	return status;
}

static int read_io(struct cxd *ci, u16 address, u8 *val)
{
	int status;
	u8 addr[3] = { 2, address&0xff, address>>8 };

	status = i2c_write(ci->i2c, ci->adr, addr, 3);
	if (!status)
		status = i2c_read(ci->i2c, ci->adr, 3, val, 1);
	return status;
}

static int write_io(struct cxd *ci, u16 address, u8 val)
{
	int status;
	u8 addr[3] = { 2, address&0xff, address>>8 };
	u8 buf[2] = { 3, val };

	status = i2c_write(ci->i2c, ci->adr, addr, 3);
	if (!status)
		status = i2c_write(ci->i2c, ci->adr, buf, 2);

	return status;
}


static int write_regm(struct cxd *ci, u8 reg, u8 val, u8 mask)
{
	int status;
	u8 b;

	status = i2c_write_reg(ci->i2c, ci->adr, 0, reg);
	if (!status) {
		status = i2c_read_reg(ci->i2c, ci->adr, 1, &b);
		if (!status) {
			b = (b & (~mask)) | val;
			status = i2c_write_reg(ci->i2c, ci->adr, 1, b);
		}
	}
	return status;
}

static int write_reg(struct cxd *ci, u8 reg, u8 val)
{
	int status;

	status = i2c_write_reg(ci->i2c, ci->adr, 0, reg);
	if (!status)
		status = i2c_write_reg(ci->i2c, ci->adr, 1, val);
		
	return status;
}

/*
#ifdef BUFFER_MODE
static int write_block(struct cxd *ci, u8 adr, u8 *data, int n)
{
	int status;
	u8 buf[256] = {1};

	status = i2c_write_reg(ci->i2c, ci->adr, 0, adr);
	if (!status) {
		ci->lastaddress = adr;
		memcpy(buf+1, data, n);
		status = i2c_write(ci->i2c, ci->adr, buf, n+1);
	}
	return status;
}
#endif
*/


static void set_mode(struct cxd *ci, int mode)
{
	if (mode == ci->mode)
		return;

	switch (mode) {
	case 0x00: /* IO mem */
		write_regm(ci, 0x06, 0x00, 0x07);
		break;
	case 0x01: /* ATT mem */
		write_regm(ci, 0x06, 0x02, 0x07);
		break;
	default:
		break;
	}
	ci->mode = mode;
}

/*
static void cam_mode(struct cxd *ci, int mode)
{
	if (mode == ci->cammode)
		return;

	switch (mode) {
	case 0x00:
		write_regm(ci, 0x20, 0x80, 0x80);
		break;
	case 0x01:
		printk(KERN_INFO "enable cam buffer mode\n");
		// write_reg(ci, 0x0d, 0x00);
		// write_reg(ci, 0x0e, 0x01);
		write_regm(ci, 0x08, 0x40, 0x40);
		// read_reg(ci, 0x12, &dummy);
		write_regm(ci, 0x08, 0x80, 0x80);
		break;
	default:
		break;
	}
	ci->cammode = mode;
}
*/


#define CHK_ERROR(s) if ((status = s)) break

static int init(struct cxd *ci)
{
	int status;

	dprintk("cxd2099: %s\n", __func__);

	mutex_lock(&ci->lock);
	ci->mode = -1;
	do {
		CHK_ERROR(write_reg(ci, 0x00, 0x00));
//		CHK_ERROR(write_reg(ci, 0x01, 0x00));
//		CHK_ERROR(write_reg(ci, 0x02, 0x10));
//		CHK_ERROR(write_reg(ci, 0x03, 0x00));
//		CHK_ERROR(write_reg(ci, 0x05, 0xFF));
//		CHK_ERROR(write_reg(ci, 0x06, 0x1F));
//		CHK_ERROR(write_reg(ci, 0x07, 0x1F));
//		CHK_ERROR(write_reg(ci, 0x08, 0x28));
//		CHK_ERROR(write_reg(ci, 0x14, 0x20));

//		CHK_ERROR(write_reg(ci, 0x09, 0x4D)); /* Input Mode C, BYPass Serial, TIVAL = low, MSB */
//		CHK_ERROR(write_reg(ci, 0x0A, 0xA7)); /* TOSTRT = 8, Mode B (gated clock), falling Edge, Serial, POL=HIGH, MSB */

		/* Sync detector */
//		CHK_ERROR(write_reg(ci, 0x0B, 0x33));
//		CHK_ERROR(write_reg(ci, 0x0C, 0x33));

//		CHK_ERROR(write_regm(ci, 0x14, 0x00, 0x0F));
//		CHK_ERROR(write_reg(ci, 0x15, ci->clk_reg_b));
//		CHK_ERROR(write_regm(ci, 0x16, 0x00, 0x0F));
//		CHK_ERROR(write_reg(ci, 0x17, ci->clk_reg_f));

//		CHK_ERROR(write_reg(ci, 0x20, 0x28)); /* Integer Divider, Falling Edge, Internal Sync, */
//		CHK_ERROR(write_reg(ci, 0x21, 0x00)); /* MCLKI = TICLK/8 */
//		CHK_ERROR(write_reg(ci, 0x22, 0x07)); /* MCLKI = TICLK/8 */


//		CHK_ERROR(write_regm(ci, 0x20, 0x80, 0x80)); /* Reset CAM state machine */

//		CHK_ERROR(write_regm(ci, 0x03, 0x02, 02));  /* Enable IREQA Interrupt */
//		CHK_ERROR(write_reg(ci, 0x01, 0x04));  /* Enable CD Interrupt */
//		CHK_ERROR(write_reg(ci, 0x00, 0x31));  /* Enable TS1,Hot Swap,Slot A */
//		CHK_ERROR(write_regm(ci, 0x09, 0x08, 0x08));  /* Put TS in bypass */

		// Shutdown everything		
		CHK_ERROR(write_reg(ci, 0x00, 0x00));
		// Enable CDA interrupt
		CHK_ERROR(write_reg(ci, 0x01, 0x04));
		// DA from CAM has priority
		CHK_ERROR(write_reg(ci, 0x02, 0x10));
		// Enable IREQA interrupt, PCMCIA timout
		CHK_ERROR(write_reg(ci, 0x03, 0x42));
		// Clears interuption bits
		CHK_ERROR(write_reg(ci, 0x05, 0xFF));
		// Reset PCMCIA slot A
		CHK_ERROR(write_reg(ci, 0x06, 0x1F));
		// Disable vcc selection for slot b
		CHK_ERROR(write_reg(ci, 0x08, 0x2C));
		// TS input serial mode C, TIVAL active LOW, MSB first, Polarity High
		CHK_ERROR(write_reg(ci, 0x09, 0x45));
		// TS output serial mode B, falling edge, MSB first, TOSTART=8
		CHK_ERROR(write_reg(ci, 0x0A, 0x47));
		// Sync detector
		CHK_ERROR(write_reg(ci, 0x0B, 0x11));
		CHK_ERROR(write_reg(ci, 0x0C, 0x11));
		// TS output clock set to 72MHz
		CHK_ERROR(write_reg(ci, 0x14, 0x20));
		CHK_ERROR(write_reg(ci, 0x15, 0x08));
		CHK_ERROR(write_reg(ci, 0x16, 0x00));
		CHK_ERROR(write_reg(ci, 0x17, 0x03));
		// HC clear delay
		CHK_ERROR(write_reg(ci, 0x18, 0x00));
		CHK_ERROR(write_reg(ci, 0x19, 0x00));
		// Internal sync detector
		CHK_ERROR(write_reg(ci, 0x20, 0x80));
		CHK_ERROR(write_reg(ci, 0x21, 0x00));
		CHK_ERROR(write_reg(ci, 0x22, 0x00));
		// TS Hot swap, Global interface enable card A
		CHK_ERROR(write_reg(ci, 0x00, 0x31));
		
		
/*		ci->cammode = -1;
#ifdef BUFFER_MODE
		cam_mode(ci, 0);
#endif
*/
	} while (0);
	mutex_unlock(&ci->lock);

	return 0;
}


static int read_attribute_mem(struct dvb_ca_en50221 *ca,
			      int slot, int address)
{
	struct cxd *ci = ca->data;
	u8 val;

	mutex_lock(&ci->lock);
	set_mode(ci, 1);
	read_pccard(ci, address, &val, 1);
	mutex_unlock(&ci->lock);
	return val;
}


static int write_attribute_mem(struct dvb_ca_en50221 *ca, int slot,
			       int address, u8 value)
{
	struct cxd *ci = ca->data;

	mutex_lock(&ci->lock);
	set_mode(ci, 1);
	write_pccard(ci, address, &value, 1);
	mutex_unlock(&ci->lock);
	return 0;
}

static int read_cam_control(struct dvb_ca_en50221 *ca,
			    int slot, u8 address)
{
	struct cxd *ci = ca->data;
	u8 val;

	mutex_lock(&ci->lock);
	set_mode(ci, 0);
	read_io(ci, address, &val);
	mutex_unlock(&ci->lock);
	return val;
}

static int write_cam_control(struct dvb_ca_en50221 *ca, int slot,
			     u8 address, u8 value)
{
	struct cxd *ci = ca->data;

	mutex_lock(&ci->lock);
	set_mode(ci, 0);
	write_io(ci, address, value);
	mutex_unlock(&ci->lock);
	return 0;
}

static int slot_reset(struct dvb_ca_en50221 *ca, int slot)
{
	struct cxd *ci = ca->data;

	dprintk("cxd2099: %s\n", __func__);

	mutex_lock(&ci->lock);
//	cam_mode(ci, 0);
//	write_reg(ci, 0x00, 0x21);
//	write_reg(ci, 0x06, 0x1F);
	write_reg(ci, 0x00, 0x31);
	write_regm(ci, 0x20, 0x80, 0x80);
//	write_reg(ci, 0x03, 0x02);
//	ci->ready = 0;
	ci->mode = -1;
	msleep(1000);
	mutex_unlock(&ci->lock);
	return 0;
}

static int slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
{
	struct cxd *ci = ca->data;

	printk(KERN_INFO "cxd2099: slot_shutdown\n");
	mutex_lock(&ci->lock);
	/* write_regm(ci, 0x09, 0x08, 0x08); */
	write_regm(ci, 0x20, 0x80, 0x80);
	write_reg(ci, 0x00, 0x00);
	ci->mode = -1;
	mutex_unlock(&ci->lock);
	return 0; /* shutdown(ci); */
}

static int slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
{
	struct cxd *ci = ca->data;

	dprintk("cxd2099: %s\n", __func__);

	mutex_lock(&ci->lock);
	// bypass CAM off
//	write_regm(ci, 0x09, 0x00, 0x08);
	
	
//	set_mode(ci, 0);
/*
#ifdef BUFFER_MODE
	cam_mode(ci, 1);
#endif
*/
	mutex_unlock(&ci->lock);
	return 0;
}


static int campoll(struct cxd *ci)
{
	u8 istat;

	read_reg(ci, 0x04, &istat);
	if (!istat)
		return 0;
	write_reg(ci, 0x05, istat);

	if (istat&0x40) {
//		ci->dr = 1;
		dprintk(KERN_INFO "cxd2099: read buffer INT\n");
	}
	if (istat&0x20)
		dprintk(KERN_INFO "cxd2099: write buffer INT\n");
	if (istat&0x80)
		dprintk(KERN_INFO "cxd2099: PCMCIA timeout\n");

	if (istat&2) {
		u8 slotstat;

		read_reg(ci, 0x01, &slotstat);
		if (!(2&slotstat)) {
			if (!ci->slot_stat) {
				ci->slot_stat |= DVB_CA_EN50221_POLL_CAM_PRESENT;
//				write_regm(ci, 0x03, 0x08, 0x08);
				dprintk(KERN_INFO "cxd2099: DVB_CA_EN50221_POLL_CAM_PRESENT\n");
			}

		} else {
			if (ci->slot_stat) {
				ci->slot_stat = 0;
//				write_regm(ci, 0x03, 0x00, 0x08);
				dprintk(KERN_INFO "cxd2099: NO CAM\n");
//				ci->ready = 0;
			}
		}
		if (istat&8 && ci->slot_stat == DVB_CA_EN50221_POLL_CAM_PRESENT) {
//			ci->ready = 1;
			ci->slot_stat |= DVB_CA_EN50221_POLL_CAM_READY;
			dprintk(KERN_INFO "cxd2099: READY\n");
		}
	}
	return 0;
}


static int poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
{
	struct cxd *ci = ca->data;
//	u8 slotstat;

	mutex_lock(&ci->lock);
	campoll(ci);
//	read_reg(ci, 0x01, &slotstat);
	mutex_unlock(&ci->lock);

	return ci->slot_stat;
}

/*
#ifdef BUFFER_MODE
static int read_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount)
{
	struct cxd *ci = ca->data;
	u8 msb, lsb;
	u16 len;

	mutex_lock(&ci->lock);
	campoll(ci);
	mutex_unlock(&ci->lock);

	dprintk(KERN_INFO "read_data\n");
	if (!ci->dr)
		return 0;

	mutex_lock(&ci->lock);
	read_reg(ci, 0x0f, &msb);
	read_reg(ci, 0x10, &lsb);
	len = (msb<<8)|lsb;
	read_block(ci, 0x12, ebuf, len);
	ci->dr = 0;
	mutex_unlock(&ci->lock);

	return len;
}

static int write_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount)
{
	struct cxd *ci = ca->data;

	mutex_lock(&ci->lock);
	dprintk(KERN_INFO "write_data %d\n", ecount);
	write_reg(ci, 0x0d, ecount>>8);
	write_reg(ci, 0x0e, ecount&0xff);
	write_block(ci, 0x11, ebuf, ecount);
	mutex_unlock(&ci->lock);
	return ecount;
}
#endif
*/

static struct dvb_ca_en50221 en_templ = {
	.read_attribute_mem  = read_attribute_mem,
	.write_attribute_mem = write_attribute_mem,
	.read_cam_control    = read_cam_control,
	.write_cam_control   = write_cam_control,
	.slot_reset          = slot_reset,
	.slot_shutdown       = slot_shutdown,
	.slot_ts_enable      = slot_ts_enable,
	.poll_slot_status    = poll_slot_status,
/*
#ifdef BUFFER_MODE
	.read_data           = read_data,
	.write_data          = write_data,
#endif
*/
};

struct dvb_ca_en50221 *cxd2099_attach(u8 adr, void *priv,
				      struct i2c_adapter *i2c)
{
	struct cxd *ci = 0;
//	u32 bitrate = 62000000;
	u8 val;

	if (i2c_read_reg(i2c, adr, 0, &val) < 0) {
		printk(KERN_ERR "No CXD2099AR detected at %02x\n", adr);
		return 0;
	}

	ci = kmalloc(sizeof(struct cxd), GFP_KERNEL);
	if (!ci)
		return 0;
	memset(ci, 0, sizeof(*ci));

	mutex_init(&ci->lock);
	ci->i2c = i2c;
	ci->adr = adr;
//	ci->lastaddress = 0xff;
//	ci->clk_reg_b = 0x4a;
//	ci->clk_reg_f = 0x1b;
//	ci->bitrate = bitrate;

	memcpy(&ci->en, &en_templ, sizeof(en_templ));
	ci->en.data = ci;
	init(ci);
	printk(KERN_INFO "Attached CXD2099AR at %02x\n", ci->adr);
	return &ci->en;
}
EXPORT_SYMBOL(cxd2099_attach);

MODULE_DESCRIPTION("cxd2099");
MODULE_AUTHOR("Ralph Metzler <rjkm@metzlerbros.de>");
MODULE_LICENSE("GPL");

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: DVB nGene CI : TS Discontinuities issues
       [not found]   ` <19909.47855.351946.831380@morden.metzler>
@ 2011-05-08 16:44     ` Issa Gorissen
  2011-05-09  0:41     ` Issa Gorissen
  1 sibling, 0 replies; 12+ messages in thread
From: Issa Gorissen @ 2011-05-08 16:44 UTC (permalink / raw)
  To: Ralph Metzler
  Cc: Linux Media Mailing List,
	"Sébastien RAILLARD (COEXSI)",
	Oliver Endriss

On 07/05/11 23:34, Ralph Metzler wrote:
> Before blaming packet loss on the CI data path also please make
> certain that you have no buffer overflows in the input part of 
> the sec device.
> In the ngene driver you can e.g. add a printk in tsin_exchange():
>
> if (dvb_ringbuffer_free(&dev->tsin_rbuf) > len) {
> ...
> } else
>     printk ("buffer overflow !!!!\n");

Ralph,

void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags)
{
    struct ngene_channel *chan = priv;
    struct ngene *dev = chan->dev;


    if (flags & DF_SWAP32)
        swap_buffer(buf, len);
    if (dev->ci.en && chan->number == 2) {
        if (dvb_ringbuffer_free(&dev->tsin_rbuf) > len) {
            dvb_ringbuffer_write(&dev->tsin_rbuf, buf, len);
            wake_up_interruptible(&dev->tsin_rbuf.queue);
        } else
            printk (KERN_WARNING "ngene transport interface:
tsin_exchange: buffer overflow !!!!\n");

        return 0;
    }
    if (chan->users > 0) {
        dvb_dmx_swfilter(&chan->demux, buf, len);
    }
    return NULL;
}



just prints the buffer overflow warning just after the module is loaded,
no other action made.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: DVB nGene CI : TS Discontinuities issues
       [not found]   ` <19909.47855.351946.831380@morden.metzler>
  2011-05-08 16:44     ` Issa Gorissen
@ 2011-05-09  0:41     ` Issa Gorissen
  2011-05-09  7:04       ` Sébastien RAILLARD (COEXSI)
  1 sibling, 1 reply; 12+ messages in thread
From: Issa Gorissen @ 2011-05-09  0:41 UTC (permalink / raw)
  To: Ralph Metzler
  Cc: Linux Media Mailing List,
	"Sébastien RAILLARD (COEXSI)",
	Oliver Endriss, Martin Vidovic

[-- Attachment #1: Type: text/plain, Size: 1968 bytes --]

On 07/05/11 23:34, Ralph Metzler wrote:
> I do not have any cxd2099 issues.
> I have a simple test program which includes a 32bit counter as payload 
> and can pump data through the CI with full speed and have no packet
> loss. I only tested decoding with an ORF stream and an Alphacrypt CAM
> but also had no problems with this.
>
> Please take care not to write data faster than it is read. Starting two
> dds will not guarantee this. To be certain you could write a small
> program which never writes more packets than input buffer size minus
> the number of read packets (and minus the stuffing null packets on ngene).
>
> Before blaming packet loss on the CI data path also please make
> certain that you have no buffer overflows in the input part of 
> the sec device.
> In the ngene driver you can e.g. add a printk in tsin_exchange():
>
> if (dvb_ringbuffer_free(&dev->tsin_rbuf) > len) {
> ...
> } else
>     printk ("buffer overflow !!!!\n");
>
>
> Regards,
> Ralph

Ralph,

As mentioned earlier, the warning message in tsin_exchange() is somewhat
useless because it is printed endlessly at module start.

However, I've written the small test (attached) and took care to not
write more than read (not taking account of null packets).

I still cannot descrambled channels. I'm using the source from 2.6.39 rc
5 with the fix from Oliver
[http://linuxtv.org/hg/~endriss/v4l-dvb/rev/3d3e6ec2d0a7].  I launched
gnutv with output to dvr, and launched my tool to read from dvr,
write/read from sec0, write to a file.

The end result is a file which is clean of null packets, but cannot be
played by mplayer (no audio, or no video, or both...)

I don't know if CAT needs to be in the stream passed through sec0 as
Sebastien mentioned, so I modified gnutv to add it to dvr.

Sebastien, Martin, could you try Ralph suggestion and post results as
well. Thx.


Please also find an update of ngene-dvb.c, the sec device now handles
blocking/non blocking access.

--
Issa

[-- Attachment #2: dvbloop.c --]
[-- Type: text/x-csrc, Size: 2128 bytes --]

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>

static void signal_handler(int _signal);
static int quit_app = 0;

int main(int argc, char *argv[])
{
	signal(SIGINT, signal_handler);

	if (argc <= 3)
		exit(1);	

	int in_fd = open(argv[1], O_RDONLY);
	int out_fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
	int tsi_fd = open(argv[3], O_RDWR);

	int rlen = 0;
	int wlen = 0;
	int rtsilen = 0;
	int wtsilen = 0;

	int BUFFY = 188 * 20;
	unsigned char buf[BUFFY];
	struct timespec sl[1];
	sl[0].tv_nsec = 250000;
	
	while (!quit_app)
	{
		// read from input (DVR or other)
		rlen = read(in_fd, buf, BUFFY);
		if (rlen > 0)
		{
			// write data to caio device
			wlen = write(tsi_fd, buf, rlen);
			if (wlen != rlen)
			{
				perror("Did not write same amount of data from input to caio!!!");
				exit(1);
			}/* else
				printf("written %d bytes in tsi\n", wlen);
	*/	}

		if (rlen < BUFFY)
		{
			nanosleep(sl, NULL);
		}

		if (rlen < 188)
			continue;


		// read data from caio device - should be decrypted
		// finding sync byte
		do {
			rtsilen = read(tsi_fd, buf, 1);
		//	printf("reading one byte: %02x from tsi\n", buf[0]);
			if (rtsilen && (buf[0] == 0x47)) {
				do {
					int i = read(tsi_fd, buf + rtsilen, 188 - rtsilen);
					rtsilen += i;
		//			printf("reading %d bytes from tsi\n", i);
				} while (rtsilen < 188);

				break;
			}
		} while (1);

//printf("sync byte found: %02x \n", buf[0]);

		wtsilen = 0;
		do {
//			printf("from tsi out: %x %x %x \n", buf[0], buf[1], buf[2]);
			if (buf[0] == 0x47 && buf[1] == 0x1F && buf[2] == 0xFF) {
				// DVB null packet, discard
			} else {
				// write packet to output
				wtsilen += write(out_fd, buf, 188);
			}

			if (rlen == wtsilen)
				break;

			rtsilen = 0;
			do {
				rtsilen += read(tsi_fd, buf + rtsilen, 188 - rtsilen);
			} while (rtsilen < 188);
		} while (1);
	}

	close(in_fd);
	close(out_fd);
	close(tsi_fd);

	exit(0);
}


static void signal_handler(int _signal)
{
	if (!quit_app)
	{
		quit_app = 1;
	}
}

[-- Attachment #3: ngene-dvb.c --]
[-- Type: text/x-csrc, Size: 7149 bytes --]

/*
 * ngene-dvb.c: nGene PCIe bridge driver - DVB functions
 *
 * Copyright (C) 2005-2007 Micronas
 *
 * Copyright (C) 2008-2009 Ralph Metzler <rjkm@metzlerbros.de>
 *                         Modifications for new nGene firmware,
 *                         support for EEPROM-copying,
 *                         support for new dual DVB-S2 card prototype
 *
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 only, as published by the Free Software Foundation.
 *
 *
 * 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 General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA
 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/poll.h>
#include <linux/io.h>
#include <asm/div64.h>
#include <linux/pci.h>
#include <linux/timer.h>
#include <linux/byteorder/generic.h>
#include <linux/firmware.h>
#include <linux/vmalloc.h>

#include "ngene.h"


/****************************************************************************/
/* COMMAND API interface ****************************************************/
/****************************************************************************/

static ssize_t ts_write(struct file *file, const char *buf,
			size_t count, loff_t *ppos)
{
	struct dvb_device *dvbdev = file->private_data;
	struct ngene_channel *chan = dvbdev->priv;
	struct ngene *dev = chan->dev;

/*
	if (wait_event_interruptible(dev->tsout_rbuf.queue,
				     dvb_ringbuffer_free
				     (&dev->tsout_rbuf) >= count) < 0)
		return 0;

	dvb_ringbuffer_write(&dev->tsout_rbuf, buf, count);

	return count;
*/
	int avail;
	char nonblock;

	nonblock = file->f_flags & O_NONBLOCK;

	if (!count)
		return 0;

	if (nonblock) {
		avail = dvb_ringbuffer_avail(&dev->tsout_rbuf);
		if (!avail)
			return -EAGAIN;
	} else {
		while (1) {
			if (wait_event_interruptible(dev->tsout_rbuf.queue,
						     dvb_ringbuffer_free
						     (&dev->tsout_rbuf) >= count) >= 0)
				break;
		}
		avail = count;
	}

	dvb_ringbuffer_write(&dev->tsout_rbuf, buf, avail);
	return avail;

}

static ssize_t ts_read(struct file *file, char *buf,
		       size_t count, loff_t *ppos)
{
	struct dvb_device *dvbdev = file->private_data;
	struct ngene_channel *chan = dvbdev->priv;
	struct ngene *dev = chan->dev;
/*	int left, avail;

	left = count;
	while (left) {
		if (wait_event_interruptible(
			    dev->tsin_rbuf.queue,
			    dvb_ringbuffer_avail(&dev->tsin_rbuf) > 0) < 0)
			return -EAGAIN;
		avail = dvb_ringbuffer_avail(&dev->tsin_rbuf);
		if (avail > left)
			avail = left;
		dvb_ringbuffer_read_user(&dev->tsin_rbuf, buf, avail);
		left -= avail;
		buf += avail;
	}
	return count;
*/
	int avail = 0;
	char nonblock;

	nonblock = file->f_flags & O_NONBLOCK;

	if (!count)
		return 0;

	if (nonblock) {
		avail = dvb_ringbuffer_avail(&dev->tsin_rbuf);
	} else {
		while (!avail) {
			if (wait_event_interruptible(
				    dev->tsin_rbuf.queue,
				    dvb_ringbuffer_avail(&dev->tsin_rbuf) > 0) < 0)
				continue;

			avail = dvb_ringbuffer_avail(&dev->tsin_rbuf);
		}
	}

	if (avail > count)
		avail = count;
	if (avail > 0)
		dvb_ringbuffer_read_user(&dev->tsin_rbuf, buf, avail);

	if (!avail)
		return -EAGAIN;
	else
		return avail;

}

static const struct file_operations ci_fops = {
	.owner   = THIS_MODULE,
	.read    = ts_read,
	.write   = ts_write,
	.open    = dvb_generic_open,
	.release = dvb_generic_release,
};

struct dvb_device ngene_dvbdev_ci = {
	.priv    = 0,
	.readers = 1,
	.writers = 1,
	.users   = 2,
	.fops    = &ci_fops,
};


/****************************************************************************/
/* DVB functions and API interface ******************************************/
/****************************************************************************/

static void swap_buffer(u32 *p, u32 len)
{
	while (len) {
		*p = swab32(*p);
		p++;
		len -= 4;
	}
}

void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags)
{
	struct ngene_channel *chan = priv;
	struct ngene *dev = chan->dev;


	if (flags & DF_SWAP32)
		swap_buffer(buf, len);
	if (dev->ci.en && chan->number == 2) {
		if (dvb_ringbuffer_free(&dev->tsin_rbuf) > len) {
			dvb_ringbuffer_write(&dev->tsin_rbuf, buf, len);
			wake_up_interruptible(&dev->tsin_rbuf.queue);
		}

		return 0;
	}
	if (chan->users > 0) {
		dvb_dmx_swfilter(&chan->demux, buf, len);
	}
	return NULL;
}

u8 fill_ts[188] = { 0x47, 0x1f, 0xff, 0x10 };

void *tsout_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags)
{
	struct ngene_channel *chan = priv;
	struct ngene *dev = chan->dev;
	u32 alen;

	alen = dvb_ringbuffer_avail(&dev->tsout_rbuf);
	alen -= alen % 188;

	if (alen < len)
		FillTSBuffer(buf + alen, len - alen, flags);
	else
		alen = len;
	dvb_ringbuffer_read(&dev->tsout_rbuf, buf, alen);
	if (flags & DF_SWAP32)
		swap_buffer((u32 *)buf, alen);
	wake_up_interruptible(&dev->tsout_rbuf.queue);
	return buf;
}



int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed)
{
	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
	struct ngene_channel *chan = dvbdmx->priv;

	if (chan->users == 0) {
		if (!chan->dev->cmd_timeout_workaround || !chan->running)
			set_transfer(chan, 1);
	}

	return ++chan->users;
}

int ngene_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
{
	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
	struct ngene_channel *chan = dvbdmx->priv;

	if (--chan->users)
		return chan->users;

	if (!chan->dev->cmd_timeout_workaround)
		set_transfer(chan, 0);

	return 0;
}

int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id,
			    int (*start_feed)(struct dvb_demux_feed *),
			    int (*stop_feed)(struct dvb_demux_feed *),
			    void *priv)
{
	dvbdemux->priv = priv;

	dvbdemux->filternum = 256;
	dvbdemux->feednum = 256;
	dvbdemux->start_feed = start_feed;
	dvbdemux->stop_feed = stop_feed;
	dvbdemux->write_to_decoder = NULL;
	dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
				      DMX_SECTION_FILTERING |
				      DMX_MEMORY_BASED_FILTERING);
	return dvb_dmx_init(dvbdemux);
}

int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev,
			       struct dvb_demux *dvbdemux,
			       struct dmx_frontend *hw_frontend,
			       struct dmx_frontend *mem_frontend,
			       struct dvb_adapter *dvb_adapter)
{
	int ret;

	dmxdev->filternum = 256;
	dmxdev->demux = &dvbdemux->dmx;
	dmxdev->capabilities = 0;
	ret = dvb_dmxdev_init(dmxdev, dvb_adapter);
	if (ret < 0)
		return ret;

	hw_frontend->source = DMX_FRONTEND_0;
	dvbdemux->dmx.add_frontend(&dvbdemux->dmx, hw_frontend);
	mem_frontend->source = DMX_MEMORY_FE;
	dvbdemux->dmx.add_frontend(&dvbdemux->dmx, mem_frontend);
	return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend);
}

^ permalink raw reply	[flat|nested] 12+ messages in thread

* RE: DVB nGene CI : TS Discontinuities issues
  2011-05-09  0:41     ` Issa Gorissen
@ 2011-05-09  7:04       ` Sébastien RAILLARD (COEXSI)
  2011-05-09 20:39         ` Issa Gorissen
  0 siblings, 1 reply; 12+ messages in thread
From: Sébastien RAILLARD (COEXSI) @ 2011-05-09  7:04 UTC (permalink / raw)
  To: 'Issa Gorissen', 'Ralph Metzler'
  Cc: 'Linux Media Mailing List', 'Oliver Endriss',
	'Martin Vidovic'



> -----Original Message-----
> From: Issa Gorissen [mailto:flop.m@usa.net]
> Sent: lundi 9 mai 2011 02:42
> To: Ralph Metzler
> Cc: Linux Media Mailing List; "Sébastien RAILLARD (COEXSI)"; Oliver
> Endriss; Martin Vidovic
> Subject: Re: DVB nGene CI : TS Discontinuities issues
> 
> On 07/05/11 23:34, Ralph Metzler wrote:
> > I do not have any cxd2099 issues.
> > I have a simple test program which includes a 32bit counter as payload
> > and can pump data through the CI with full speed and have no packet
> > loss. I only tested decoding with an ORF stream and an Alphacrypt CAM
> > but also had no problems with this.
> >
> > Please take care not to write data faster than it is read. Starting
> > two dds will not guarantee this. To be certain you could write a small
> > program which never writes more packets than input buffer size minus
> > the number of read packets (and minus the stuffing null packets on
> ngene).
> >
> > Before blaming packet loss on the CI data path also please make
> > certain that you have no buffer overflows in the input part of the sec
> > device.
> > In the ngene driver you can e.g. add a printk in tsin_exchange():
> >
> > if (dvb_ringbuffer_free(&dev->tsin_rbuf) > len) { ...
> > } else
> >     printk ("buffer overflow !!!!\n");
> >
> >
> > Regards,
> > Ralph
> 
> Ralph,
> 
> As mentioned earlier, the warning message in tsin_exchange() is somewhat
> useless because it is printed endlessly at module start.
> 
> However, I've written the small test (attached) and took care to not
> write more than read (not taking account of null packets).
> 
> I still cannot descrambled channels. I'm using the source from 2.6.39 rc
> 5 with the fix from Oliver
> [http://linuxtv.org/hg/~endriss/v4l-dvb/rev/3d3e6ec2d0a7].  I launched
> gnutv with output to dvr, and launched my tool to read from dvr,
> write/read from sec0, write to a file.
> 
> The end result is a file which is clean of null packets, but cannot be
> played by mplayer (no audio, or no video, or both...)
> 
> I don't know if CAT needs to be in the stream passed through sec0 as
> Sebastien mentioned, so I modified gnutv to add it to dvr.
> 

Yes, the CAT table is mandatory, it must be sent to the CAM, as well as :
* the EMM PID referenced in the CAT
* all the private descriptors (binary blobs) in the PMT and, of course
* the ECM PID referenced in the PMT

Of course, the CAM must be initialized, all the necessary CAM resources must
be initialized and a CA_PMT object must be sent through the CAM command
channel to ask for unscrambling of needed channels.

That why it's better to send directly the raw TS output of the demodulator
directly in the CAM.
And then doing the demux filtering stuff on the TS stream coming from the
CAM (once unscrambled).

> Sebastien, Martin, could you try Ralph suggestion and post results as
> well. Thx.
> 
> 
> Please also find an update of ngene-dvb.c, the sec device now handles
> blocking/non blocking access.
> 
> --
> Issa


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: DVB nGene CI : TS Discontinuities issues
  2011-05-09  7:04       ` Sébastien RAILLARD (COEXSI)
@ 2011-05-09 20:39         ` Issa Gorissen
  0 siblings, 0 replies; 12+ messages in thread
From: Issa Gorissen @ 2011-05-09 20:39 UTC (permalink / raw)
  To: "Sébastien RAILLARD (COEXSI)"
  Cc: 'Ralph Metzler', 'Linux Media Mailing List',
	'Oliver Endriss', 'Martin Vidovic'

On 09/05/11 09:04, Sébastien RAILLARD (COEXSI) wrote:
>> I don't know if CAT needs to be in the stream passed through sec0 as
>> Sebastien mentioned, so I modified gnutv to add it to dvr.
>>
> Yes, the CAT table is mandatory, it must be sent to the CAM, as well as :
> * the EMM PID referenced in the CAT
> * all the private descriptors (binary blobs) in the PMT and, of course
> * the ECM PID referenced in the PMT
>
> Of course, the CAM must be initialized, all the necessary CAM resources must
> be initialized and a CA_PMT object must be sent through the CAM command
> channel to ask for unscrambling of needed channels.
>
> That why it's better to send directly the raw TS output of the demodulator
> directly in the CAM.
> And then doing the demux filtering stuff on the TS stream coming from the
> CAM (once unscrambled).

Thx Sebastien,

Will check this out with gnutv and report.

I think gnutv does all the init stuff you mentioned about the CAM. I
will check for the possibly missing PSI packets gnutv might exclude.

--
Issa

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: DVB nGene CI : TS Discontinuities issues
  2012-02-26 17:11     ` Anssi Hannula
@ 2012-02-26 22:14       ` Ralph Metzler
  0 siblings, 0 replies; 12+ messages in thread
From: Ralph Metzler @ 2012-02-26 22:14 UTC (permalink / raw)
  To: Anssi Hannula
  Cc: Issa Gorissen, Linux Media Mailing List, S-bastien RAILLARD,
	Oliver Endriss

Anssi Hannula writes:
 > > I had it running for an hour and had no discontinuities (except at
 > > restarts, might have to look into buffer flushing).
 > > I tested it with nGene and Octopus boards on an Asus ION2 board and on a
 > > Marvell Kirkwood based ARM board.
 > 
 > Should your test code (quoted below) work with e.g. Octopus DDBridge on
 > vanilla 3.2.6 kernel, without any additional initialization needed
 > through ca0 or so?
 > 
 > When I try it here like that, the reader thread simply blocks
 > indefinitely on the first read, while the writer thread continues to
 > write packets into the device.
 > Am I missing something, or is this a bug?


Yes, it should work as it is. 
I assume you adjusted the adapter numbers of course.



Regards,
Ralph

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: DVB nGene CI : TS Discontinuities issues
  2011-05-13 11:54   ` Ralph Metzler
@ 2012-02-26 17:11     ` Anssi Hannula
  2012-02-26 22:14       ` Ralph Metzler
  0 siblings, 1 reply; 12+ messages in thread
From: Anssi Hannula @ 2012-02-26 17:11 UTC (permalink / raw)
  To: Ralph Metzler
  Cc: Issa Gorissen, Linux Media Mailing List, S-bastien RAILLARD,
	Oliver Endriss

Hello,

13.05.2011 14:54, Ralph Metzler kirjoitti:
> Below my test code. You just need to adjust the device name.
> 
> I had it running for an hour and had no discontinuities (except at
> restarts, might have to look into buffer flushing).
> I tested it with nGene and Octopus boards on an Asus ION2 board and on a
> Marvell Kirkwood based ARM board.

Should your test code (quoted below) work with e.g. Octopus DDBridge on
vanilla 3.2.6 kernel, without any additional initialization needed
through ca0 or so?

When I try it here like that, the reader thread simply blocks
indefinitely on the first read, while the writer thread continues to
write packets into the device.
Am I missing something, or is this a bug?

> Btw., what hardware exactly are you using? 
> Which DVB card version, CI type, motherboard chipset?

I'm not sure what do you need, exactly, but here's the relevant section
of the kernel log. Motherboard chipset is Intel X58. Feel free to ask
for anything else.

[ 1333.801243] Digital Devices PCIE bridge driver, Copyright (C) 2010-11
Digital Devices GmbH
[ 1333.801302] DDBridge 0000:08:00.0: PCI INT A -> GSI 32 (level, low)
-> IRQ 32
[ 1333.801314] DDBridge driver detected: Digital Devices Octopus DVB adapter
[ 1333.801357] HW 00010004 FW 00010001
[ 1333.802371] Port 0 (TAB 1): DUAL DVB-C/T
[ 1333.802819] Port 1 (TAB 2): CI
[ 1333.803785] Port 2 (TAB 3): DUAL DVB-C/T
[ 1333.804369] Port 3 (TAB 4): NO MODULE
[ 1333.805176] DVB: registering new adapter (DDBridge)
[ 1333.824506] drxk: detected a drx-3913k, spin A3, xtal 27.000 MHz
[ 1334.313799] DRXK driver version 0.9.4300
[ 1337.120786] DVB: registering adapter 0 frontend 0 (DRXK DVB-C)...
[ 1337.120996] DVB: registering adapter 0 frontend 0 (DRXK DVB-T)...
[ 1337.121165] DVB: registering new adapter (DDBridge)
[ 1337.151565] drxk: detected a drx-3913k, spin A3, xtal 27.000 MHz
[ 1337.653400] DRXK driver version 0.9.4300
[ 1340.467888] DVB: registering adapter 1 frontend 0 (DRXK DVB-C)...
[ 1340.468097] DVB: registering adapter 1 frontend 0 (DRXK DVB-T)...
[ 1340.468203] DVB: registering new adapter (DDBridge)
[ 1340.477045] Attached CXD2099AR at 40
[ 1340.477502] DVB: registering new adapter (DDBridge)
[ 1340.498717] drxk: detected a drx-3913k, spin A3, xtal 27.000 MHz
[ 1340.978018] DRXK driver version 0.9.4300
[ 1343.784964] DVB: registering adapter 3 frontend 0 (DRXK DVB-C)...
[ 1343.785168] DVB: registering adapter 3 frontend 0 (DRXK DVB-T)...
[ 1343.785322] DVB: registering new adapter (DDBridge)
[ 1343.805712] drxk: detected a drx-3913k, spin A3, xtal 27.000 MHz
[ 1344.295293] DRXK driver version 0.9.4300
[ 1347.062278] DVB: registering adapter 4 frontend 0 (DRXK DVB-C)...
[ 1347.062490] DVB: registering adapter 4 frontend 0 (DRXK DVB-T)...
[ 1347.816555] dvb_ca adapter 2: DVB CAM detected and initialised
successfully


> Regards,
> Ralph
> 
> 
> 
> #include <stdio.h>
> #include <ctype.h>
> #include <string.h>
> #include <unistd.h>
> #include <sys/types.h>
> #include <sys/stat.h>
> #include <stdint.h>
> #include <stdlib.h>
> #include <fcntl.h>
> #include <sys/ioctl.h>
> #include <pthread.h>
> 
> uint8_t fill[188]={0x47, 0x1f, 0xff, 0x10,
>    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
>    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
>    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
>    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
>    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
>    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
>    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
>    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
>    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
>    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
>    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
> 		   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
> 
> uint8_t ts[188]={0x47, 0x0a, 0xaa, 0x00 };
> 
> 
> void proc_buf(uint8_t *buf, uint32_t *d)
> {
> 	uint32_t c;
> 
> 	if (buf[1]==0x1f && buf[2]==0xff) {
> 		//printf("fill\n");
> 		return;
> 	}
> 	if (buf[1]==0x9f && buf[2]==0xff) {
> 		//printf("fill\n");
> 		return;
> 	}
> 	if (buf[1]!=0x0a || buf[2]!=0xaa)
> 		return;
> 	c=(buf[4]<<24)|(buf[5]<<16)|(buf[6]<<8)|buf[7];
> 	if (c!=*d) {
> 		printf("CONT ERROR %08x %08x\n", c, *d);
> 		*d=c;
> 	} else {
> 		if (memcmp(ts+8, buf+8, 180))
> 			printf("error\n");
> 		if (!(c&0xffff))
> 			printf("R %d\n", c);
> 	}
> 	(*d)++;
> }
> 
> void *get_ts(void *a)
> {
> 	uint8_t buf[188*1024];
> 	int len, off;
> 
> 	int fdi=open("/dev/dvb/adapter4/sec0", O_RDONLY);
> 	uint32_t d=0;
> 
> 	while (1) {
> 		len=read(fdi, buf, 188*1024);
> 		if (len<0)
> 			continue;
> 		if (buf[0]!=0x47) { //should not happen
> 			read(fdi, buf, 1);
> 			continue;
> 		}
> 		for (off=0; off<len; off+=188) {
> 			proc_buf(buf+off, &d);
> 		}
> 	}	
> }
> 
> #define SNUM 671
> void send(void)
> {
> 	uint8_t buf[188*SNUM], *cts;
> 	int i;
> 	uint32_t c=0;
> 	int fdo;
> 
> 	fdo=open("/dev/dvb/adapter4/sec0", O_WRONLY);
> 
> 
> 	while (1) {
> 		for (i=0; i<SNUM; i++) {
> 			cts=buf+i*188;
> 			memcpy(cts, ts, 188);
> 			cts[4]=(c>>24);
> 			cts[5]=(c>>16);
> 			cts[6]=(c>>8);
> 			cts[7]=c;
> 			//write(fdo, fill, 188);
> 			//printf("S %d\n", c); 
> 			c++;
> 			//usleep(100000+0xffff&rand());
> 			//usleep(1000);
> 		}
> 		write(fdo, buf, 188*SNUM);
> 	}
> }
> 
> 
> int main()
> {
> 	pthread_t th;
> 
> 	memset(ts+8, 180, 0x5a);
> 	pthread_create(&th, NULL, get_ts, NULL);
> 	send();
> }
> 
>  
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


-- 
Anssi Hannula

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: DVB nGene CI : TS Discontinuities issues
  2011-05-12 20:40 ` Issa Gorissen
@ 2011-05-13 11:54   ` Ralph Metzler
  2012-02-26 17:11     ` Anssi Hannula
  0 siblings, 1 reply; 12+ messages in thread
From: Ralph Metzler @ 2011-05-13 11:54 UTC (permalink / raw)
  To: Issa Gorissen
  Cc: Ralph Metzler, Linux Media Mailing List, S-bastien RAILLARD,
	Oliver Endriss

Issa Gorissen writes:
 > On 11/05/11 15:12, Issa Gorissen wrote:
 > > From: Ralph Metzler <rjkm@metzlerbros.de>
 > >> Issa Gorissen writes:
 > >>  > Could you please take a look at the cxd2099 issues ?
 > >>  > 
 > >>  > I have attached a version with my changes. I have tested a lot of
 > >>  > different settings with the help of the chip datasheet.
 > >>  > 
 > >>  > Scrambled programs are not handled correctly. I don't know if it is the
 > >>  > TICLK/MCLKI which is too high or something, or the sync detector ? Also,
 > >>  > as we have to set the TOCLK to max of 72MHz, there are way too much null
 > >>  > packets added. Is there a way to solve this ?
 > >>
 > >> I do not have any cxd2099 issues.
 > >> I have a simple test program which includes a 32bit counter as payload 
 > >> and can pump data through the CI with full speed and have no packet
 > >> loss. I only tested decoding with an ORF stream and an Alphacrypt CAM
 > >> but also had no problems with this.
 > >>
 > >> Please take care not to write data faster than it is read. Starting two
 > >> dds will not guarantee this. To be certain you could write a small
 > >> program which never writes more packets than input buffer size minus
 > >> the number of read packets (and minus the stuffing null packets on ngene).
 > >>
 > >> Before blaming packet loss on the CI data path also please make
 > >> certain that you have no buffer overflows in the input part of 
 > >> the sec device.
 > >> In the ngene driver you can e.g. add a printk in tsin_exchange():
 > >>
 > >> if (dvb_ringbuffer_free(&dev->tsin_rbuf) > len) {
 > >> ...
 > >> } else
 > >>     printk ("buffer overflow !!!!\n");
 > >>
 > >>
 > >> Regards,
 > >> Ralph
 > Ralph,
 > 
OB > Done some more tests, from by test tool, I found out that I have to skip
 > (rather often) bytes to find the sync one when reading from sec0. I
 > thought I only needed to do that at the start of the stream, not in the
 > middle; because I always read/write 188 bytes from it.

This should not happen. 
Is there any difference regarding this alignment problem if the CI is inserted or not?

 
 > Could you share your test code ? I'm finding it difficult to interact
 > with this sec0 implementation.


Below my test code. You just need to adjust the device name.

I had it running for an hour and had no discontinuities (except at
restarts, might have to look into buffer flushing).
I tested it with nGene and Octopus boards on an Asus ION2 board and on a
Marvell Kirkwood based ARM board.

Btw., what hardware exactly are you using? 
Which DVB card version, CI type, motherboard chipset?


Regards,
Ralph



#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <pthread.h>

uint8_t fill[188]={0x47, 0x1f, 0xff, 0x10,
   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
		   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };

uint8_t ts[188]={0x47, 0x0a, 0xaa, 0x00 };


void proc_buf(uint8_t *buf, uint32_t *d)
{
	uint32_t c;

	if (buf[1]==0x1f && buf[2]==0xff) {
		//printf("fill\n");
		return;
	}
	if (buf[1]==0x9f && buf[2]==0xff) {
		//printf("fill\n");
		return;
	}
	if (buf[1]!=0x0a || buf[2]!=0xaa)
		return;
	c=(buf[4]<<24)|(buf[5]<<16)|(buf[6]<<8)|buf[7];
	if (c!=*d) {
		printf("CONT ERROR %08x %08x\n", c, *d);
		*d=c;
	} else {
		if (memcmp(ts+8, buf+8, 180))
			printf("error\n");
		if (!(c&0xffff))
			printf("R %d\n", c);
	}
	(*d)++;
}

void *get_ts(void *a)
{
	uint8_t buf[188*1024];
	int len, off;

	int fdi=open("/dev/dvb/adapter4/sec0", O_RDONLY);
	uint32_t d=0;

	while (1) {
		len=read(fdi, buf, 188*1024);
		if (len<0)
			continue;
		if (buf[0]!=0x47) { //should not happen
			read(fdi, buf, 1);
			continue;
		}
		for (off=0; off<len; off+=188) {
			proc_buf(buf+off, &d);
		}
	}	
}

#define SNUM 671
void send(void)
{
	uint8_t buf[188*SNUM], *cts;
	int i;
	uint32_t c=0;
	int fdo;

	fdo=open("/dev/dvb/adapter4/sec0", O_WRONLY);


	while (1) {
		for (i=0; i<SNUM; i++) {
			cts=buf+i*188;
			memcpy(cts, ts, 188);
			cts[4]=(c>>24);
			cts[5]=(c>>16);
			cts[6]=(c>>8);
			cts[7]=c;
			//write(fdo, fill, 188);
			//printf("S %d\n", c); 
			c++;
			//usleep(100000+0xffff&rand());
			//usleep(1000);
		}
		write(fdo, buf, 188*SNUM);
	}
}


int main()
{
	pthread_t th;

	memset(ts+8, 180, 0x5a);
	pthread_create(&th, NULL, get_ts, NULL);
	send();
}

 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: DVB nGene CI : TS Discontinuities issues
  2011-05-11 13:12 Issa Gorissen
  2011-05-11 13:35 ` Sébastien RAILLARD (COEXSI)
@ 2011-05-12 20:40 ` Issa Gorissen
  2011-05-13 11:54   ` Ralph Metzler
  1 sibling, 1 reply; 12+ messages in thread
From: Issa Gorissen @ 2011-05-12 20:40 UTC (permalink / raw)
  To: Ralph Metzler
  Cc: Linux Media Mailing List, S-bastien RAILLARD, Oliver Endriss

On 11/05/11 15:12, Issa Gorissen wrote:
> From: Ralph Metzler <rjkm@metzlerbros.de>
>> Issa Gorissen writes:
>>  > Could you please take a look at the cxd2099 issues ?
>>  > 
>>  > I have attached a version with my changes. I have tested a lot of
>>  > different settings with the help of the chip datasheet.
>>  > 
>>  > Scrambled programs are not handled correctly. I don't know if it is the
>>  > TICLK/MCLKI which is too high or something, or the sync detector ? Also,
>>  > as we have to set the TOCLK to max of 72MHz, there are way too much null
>>  > packets added. Is there a way to solve this ?
>>
>> I do not have any cxd2099 issues.
>> I have a simple test program which includes a 32bit counter as payload 
>> and can pump data through the CI with full speed and have no packet
>> loss. I only tested decoding with an ORF stream and an Alphacrypt CAM
>> but also had no problems with this.
>>
>> Please take care not to write data faster than it is read. Starting two
>> dds will not guarantee this. To be certain you could write a small
>> program which never writes more packets than input buffer size minus
>> the number of read packets (and minus the stuffing null packets on ngene).
>>
>> Before blaming packet loss on the CI data path also please make
>> certain that you have no buffer overflows in the input part of 
>> the sec device.
>> In the ngene driver you can e.g. add a printk in tsin_exchange():
>>
>> if (dvb_ringbuffer_free(&dev->tsin_rbuf) > len) {
>> ...
>> } else
>>     printk ("buffer overflow !!!!\n");
>>
>>
>> Regards,
>> Ralph
Ralph,

Done some more tests, from by test tool, I found out that I have to skip
(rather often) bytes to find the sync one when reading from sec0. I
thought I only needed to do that at the start of the stream, not in the
middle; because I always read/write 188 bytes from it.

Could you share your test code ? I'm finding it difficult to interact
with this sec0 implementation.

Thx
--
Issa

^ permalink raw reply	[flat|nested] 12+ messages in thread

* RE: DVB nGene CI : TS Discontinuities issues
  2011-05-11 13:12 Issa Gorissen
@ 2011-05-11 13:35 ` Sébastien RAILLARD (COEXSI)
  2011-05-12 20:40 ` Issa Gorissen
  1 sibling, 0 replies; 12+ messages in thread
From: Sébastien RAILLARD (COEXSI) @ 2011-05-11 13:35 UTC (permalink / raw)
  To: 'Issa Gorissen', 'Ralph Metzler'
  Cc: 'Linux Media Mailing List', 'Oliver Endriss'



> -----Original Message-----
> From: Issa Gorissen [mailto:flop.m@usa.net]
> Sent: mercredi 11 mai 2011 15:13
> To: Ralph Metzler
> Cc: Linux Media Mailing List; S-bastien RAILLARD; Oliver Endriss
> Subject: Re: DVB nGene CI : TS Discontinuities issues
> 
> From: Ralph Metzler <rjkm@metzlerbros.de>
> > Issa Gorissen writes:
> >  > Could you please take a look at the cxd2099 issues ?
> >  >
> >  > I have attached a version with my changes. I have tested a lot of
> > > different settings with the help of the chip datasheet.
> >  >
> >  > Scrambled programs are not handled correctly. I don't know if it is
> > the  > TICLK/MCLKI which is too high or something, or the sync
> > detector ? Also,  > as we have to set the TOCLK to max of 72MHz, there
> > are way too much null  > packets added. Is there a way to solve this ?
> >
> > I do not have any cxd2099 issues.
> > I have a simple test program which includes a 32bit counter as payload
> > and can pump data through the CI with full speed and have no packet
> > loss. I only tested decoding with an ORF stream and an Alphacrypt CAM
> > but also had no problems with this.
> >
> > Please take care not to write data faster than it is read. Starting
> > two dds will not guarantee this. To be certain you could write a small
> > program which never writes more packets than input buffer size minus
> > the number of read packets (and minus the stuffing null packets on
> ngene).
> >
> > Before blaming packet loss on the CI data path also please make
> > certain that you have no buffer overflows in the input part of the sec
> > device.
> > In the ngene driver you can e.g. add a printk in tsin_exchange():
> >
> > if (dvb_ringbuffer_free(&dev->tsin_rbuf) > len) { ...
> > } else
> >     printk ("buffer overflow !!!!\n");
> >
> >
> > Regards,
> > Ralph
> 
> 
> Ralph,
> 
> Please find my testing tool for the decryption attached. The idea is to
> write
> 5 packets and read them back from the CAM.
> 
> My input is a raw ts captured with a gnutv I modified with a demux
> filter of 0x2000. Gnutv outputs at dvr and dvbloop reads from it,
> process via sec0 and writes output to a file.
> 
> The channel I selected has been decrypted. Only problem is I have
> artifacts in the image and the sound.
> 
> Do you have any idea of what I should improve from my test tool to fix
> that issue ?
> 
> 

Good news, it seems that you managed to get it working!
You can check that your input and output TS files doesn't have issues or
discontinuities.

If you have access to a Windows running computer, you can test your TS files
with a small analyzer I wrote:
http://www.coexsi.fr/publications/mpegts-analyzer/


> Thx,
> --
> Issa



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: DVB nGene CI : TS Discontinuities issues
@ 2011-05-11 13:12 Issa Gorissen
  2011-05-11 13:35 ` Sébastien RAILLARD (COEXSI)
  2011-05-12 20:40 ` Issa Gorissen
  0 siblings, 2 replies; 12+ messages in thread
From: Issa Gorissen @ 2011-05-11 13:12 UTC (permalink / raw)
  To: Ralph Metzler
  Cc: Linux Media Mailing List, S-bastien RAILLARD, Oliver Endriss

[-- Attachment #1: Type: text/plain, Size: 2071 bytes --]

From: Ralph Metzler <rjkm@metzlerbros.de>
> Issa Gorissen writes:
>  > Could you please take a look at the cxd2099 issues ?
>  > 
>  > I have attached a version with my changes. I have tested a lot of
>  > different settings with the help of the chip datasheet.
>  > 
>  > Scrambled programs are not handled correctly. I don't know if it is the
>  > TICLK/MCLKI which is too high or something, or the sync detector ? Also,
>  > as we have to set the TOCLK to max of 72MHz, there are way too much null
>  > packets added. Is there a way to solve this ?
> 
> I do not have any cxd2099 issues.
> I have a simple test program which includes a 32bit counter as payload 
> and can pump data through the CI with full speed and have no packet
> loss. I only tested decoding with an ORF stream and an Alphacrypt CAM
> but also had no problems with this.
> 
> Please take care not to write data faster than it is read. Starting two
> dds will not guarantee this. To be certain you could write a small
> program which never writes more packets than input buffer size minus
> the number of read packets (and minus the stuffing null packets on ngene).
> 
> Before blaming packet loss on the CI data path also please make
> certain that you have no buffer overflows in the input part of 
> the sec device.
> In the ngene driver you can e.g. add a printk in tsin_exchange():
> 
> if (dvb_ringbuffer_free(&dev->tsin_rbuf) > len) {
> ...
> } else
>     printk ("buffer overflow !!!!\n");
> 
> 
> Regards,
> Ralph


Ralph,

Please find my testing tool for the decryption attached. The idea is to write
5 packets and read them back from the CAM.

My input is a raw ts captured with a gnutv I modified with a demux filter of
0x2000. Gnutv outputs at dvr and dvbloop reads from it, process via sec0 and
writes output to a file.

The channel I selected has been decrypted. Only problem is I have artifacts in
the image and the sound.

Do you have any idea of what I should improve from my test tool to fix that
issue ?


Thx,
--
Issa


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: dvbloop.c --]
[-- Type: text/x-csrc; name="dvbloop.c", Size: 2445 bytes --]

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>

static void signal_handler(int _signal);
static int quit_app = 0;

int main(int argc, char *argv[])
{
	signal(SIGINT, signal_handler);

	if (argc <= 3)
		exit(1);	

	int in_fd = open(argv[1], O_RDONLY);
	int out_fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
	int tsi_fd = open(argv[3], O_RDWR);

	int rlen = 0;
	int wlen = 0;
	int rtsilen = 0;
	int wtsilen = 0;

	int BUFFY = 188 * 5;
	unsigned char buf[BUFFY];
	struct timespec sl[1];
	sl[0].tv_nsec = 250000;
	
	while (!quit_app)
	{
		// read from input (DVR or other)
		rlen = 0;
		while (rlen < BUFFY) {
			int i = read(in_fd, buf + rlen, BUFFY - rlen);
			if (!i) {
				quit_app = 1;
				continue;
			}
			rlen += i;
		}
		
		// write data to caio device
		wlen = write(tsi_fd, buf, rlen);
		if (wlen != rlen)
		{
			perror("Did not write same amount of data from input to caio!!!");
			exit(1);
		}/* else
			printf("written %d bytes in tsi\n", wlen);
	*/

		// read data from caio device - should be decrypted
		// finding sync byte
		do {
			buf[0] = 0;
			while (buf[0] != 0x47) {
				rtsilen = read(tsi_fd, buf, 1);
			}
			
			if (buf[0] == 0x47) {
				do {
					int i = read(tsi_fd, buf + rtsilen, 188 - rtsilen);
					rtsilen += i;
//					printf("reading %d bytes from tsi\n", i);
				} while (rtsilen < 188);

				break;
			}
		} while (1);

//printf("sync byte found: %02x \n", buf[0]);

		wtsilen = 0;
		int nulls = 0;
		do {
			if (buf[0] == 0x47 && buf[1] == 0x1F && buf[2] == 0xFF) {
				++nulls;
				if (nulls > 100)
					break;

//				printf("null packet ");
				// DVB null packet, discard
			} else {
//			printf("\nfrom tsi out: %x %x %x \n", buf[0], buf[1], buf[2]);
				// write packet to output
				int i = write(out_fd, buf, 188);
				if (i < 188) {
					perror("Did not write 188 bytes to output file!!!");
				}
				wtsilen += i;
			}

			if (rlen == wtsilen || quit_app)
				break;

			rtsilen = 0;
			do {
				rtsilen += read(tsi_fd, buf + rtsilen, 188 - rtsilen);
			} while (rtsilen < 188);
		} while (1);
	}

	close(in_fd);
	close(out_fd);
	close(tsi_fd);

	exit(0);
}


static void signal_handler(int _signal)
{
	if (!quit_app)
	{
		quit_app = 1;
	}
}

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2012-02-26 22:14 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-03 10:59 DVB nGene CI : TS Discontinuities issues Sébastien RAILLARD (COEXSI)
2011-05-07 15:15 ` Issa Gorissen
     [not found]   ` <19909.47855.351946.831380@morden.metzler>
2011-05-08 16:44     ` Issa Gorissen
2011-05-09  0:41     ` Issa Gorissen
2011-05-09  7:04       ` Sébastien RAILLARD (COEXSI)
2011-05-09 20:39         ` Issa Gorissen
2011-05-11 13:12 Issa Gorissen
2011-05-11 13:35 ` Sébastien RAILLARD (COEXSI)
2011-05-12 20:40 ` Issa Gorissen
2011-05-13 11:54   ` Ralph Metzler
2012-02-26 17:11     ` Anssi Hannula
2012-02-26 22:14       ` Ralph Metzler

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.