Mailing List archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[linux-dvb] Re: [vdr] Re: AC3 over Soundcard (live and replay) (Was: AC3 5.1 - can someone "fix" -a in VDR 1.1.x - Please :)
- To: vdr@linuxtv.org
- Subject: [linux-dvb] Re: [vdr] Re: AC3 over Soundcard (live and replay) (Was: AC3 5.1 - can someone "fix" -a in VDR 1.1.x - Please :)
- From: "Dr. Werner Fink" <werner@suse.de>
- Date: Wed, 29 Jan 2003 11:34:35 +0100
- Cc: linux-dvb@linuxtv.org
- Content-disposition: inline
- Content-type: text/plain; charset=us-ascii
- In-reply-to: <20030128200945.GA32407@ulima.unil.ch>
- Organization: SuSE GmbH
- References: <fc.1efb34b71efb34b73b9aca00f5259dae.3a1e28@stageholding.de> <EIEBILCCPKIFBHCMGDIIGEOPCEAA.christian.jacobsen@stageholding.de> <20030128140519.GA8182@boole.suse.de> <20030128200945.GA32407@ulima.unil.ch>
- Sender: linux-dvb-bounce@linuxtv.org
- User-agent: Mutt/1.4i
On Tue, Jan 28, 2003 at 09:09:45PM +0100, Gregoire Favre wrote:
> Hello,
>
> does that mean that we need a soundcard to use AC3 with DVB?
>
> It took me lots of hard work to have an optical cable connecting my 5.1
> to the DVB-s (I am not an electronic fan at all...), and all sent to
> this list wasn't working for me...
>
> Wouldn't it be possible to have a plugin that use the output of the
> DVB-s?
>
> Should I need a souncard?
> Or the:
> * It should be possible to do the `AC3 warpped into PCM'
> within the DVB driver (even for Live TV!) because the
> full featured cards provide a S/P-DIF out.
If the firmware is stable enough to do transfer the Dolby digital pid
into kernel space and receive the AC3 warped into PCM which its self
is warped into a private stream 1 with the sub id for linear PCM [1]
_together_ with receiving OSD bitmaps and transferring EPG data and/or
recording data ... this _will_ work!
The last time I've tried that I've got on four starts three freezes.
OK it was an old driver with the first firmware for the NEWSTRUCT.
Maybe this is possible with the current driver and its firmware.
Nevertheless I've never got any answer from convergence nor from
the Metzler brothers on my questions and submitted code.
(The question was: Is it possible to do that in the firmware without
transfer into kernel space).
I'm not willingly to do any more to do more investigation in that
direction. IMHO it can also done in users space if the firmware
is stable (and fast) enough. OK, the disadvantage is the latency
lost due to the copy_to_user/copy_from_user together with the necessary
schedule() calls ... because the driver doesn't know about memory
mapping.
Werner
[1] ... for the sub id I've used the following extension which
I've used in send_ipack() in dvb_filter.c ... maybe it could
be also used in instant_repack() directly. The value
lpcmh[6] == 0x81 seems to enable none audio S/P-DIF transmissions
(at least my Pioneer VSA-E07 belives that) besides the magic
PCM start words for none audio in the 16 bit payload of the
32bit S/P-DIF words.
------------------------------- warp2pcm.h ---------------------------
#ifndef _WARP_2_PCM_
#define _WARP_2_PCM_
# define USE_MAXIPACK
# ifndef USE_MAXIPACK
# else
# endif
//# define DSM_TRICK
# define USE_EXTENSION_STD
typedef struct _pcm_s {
uint8_t *magic;
uint8_t *tail;
int msize;
int count;
} pcm_t;
static inline void framecpy(uint8_t *pts, pcm_t pcm,
void (*fcpy)(u8*, int), AudioInfo ai, u32 payload)
{
uint8_t start[9] = { 0x00, 0x00, 0x01, PRIVATE_STREAM1, };
uint8_t lpcmh[7] = {aLPCM, 0xff, 0x00, 0x00, 0x00, 0x00, 0x81};
static const uint8_t zero[2048];
int has_pts = (pts[1] != 0);
int fsize = 0;
fsize += sizeof(start);
fsize += sizeof(lpcmh);
fsize += pts[1];
fsize += pcm.msize;
fsize += ai.framesize;
if (fsize < sizeof(zero))
fsize = sizeof(zero);
if (fsize > sizeof(zero))
fsize = 2*sizeof(zero);
switch (ai.frequency) {
case 32000:
lpcmh[5] = 0x31;
break;
case 44100:
lpcmh[5] = 0x21;
break;
default:
case 48000:
lpcmh[5] = 0x01;
break;
}
start[6] = 0x80; /* Most 0x80 or 0x81 if copy bit is set */
start[7] = pts[0]; /* PTS flags */
start[8] = pts[1]; /* PTS field length */
while (pcm.count > 0) {
int lenght = fsize;
int size = lenght - sizeof(lpcmh);
if (has_pts)
size -= start[8]; /* pts[1] and maybe more */
if (pcm.count < size) {
lenght -= (size - pcm.count);
size = pcm.count;
}
lenght -= 6;
start[4] = (lenght >> 8) & 0xff;
start[5] = (lenght) & 0xff;
/*
* Start this frame
*/
fcpy(start, sizeof(start));
/*
* PTS follows if any
*/
if (has_pts)
fcpy(&pts[2], pts[1]);
/*
* Payload follows: first the linear PCM switch
*/
fcpy(lpcmh, sizeof(lpcmh));
/*
* Here the data will be mapped into 1536 audio samples
* (6144 bytes for 16 bit stereo) and zero padded.
*/
if (payload) {
if (pcm.count == 6144) {
fcpy(pcm.magic, pcm.msize);
pcm.count -= pcm.msize;
size -= pcm.msize;
}
if (payload <= size) {
fcpy(pcm.tail, payload);
pcm.tail += payload;
pcm.count -= payload;
size -= payload;
payload = 0;
} else {
fcpy(pcm.tail, size);
pcm.tail += size;
pcm.count -= size;
payload -= size;
size = 0;
}
}
/*
* Fillup the rest with zeros
*/
if (size) {
while (size > sizeof(zero)) {
fcpy((u8*)zero, sizeof(zero));
pcm.count -= sizeof(zero);
size -= sizeof(zero);
}
fcpy((u8*)zero, size);
pcm.count -= size;
size = 0;
}
/*
* Clear PTS for follow ups
*/
has_pts = 0;
start[7] = 0x00;
start[8] = 0x00;
}
}
static inline void init2pcm(uint8_t *pts, ipack *p, AudioInfo ai);
static inline void warp2pcm(ipack *p, int offset, AudioInfo ai)
{
pcm_t pcm;
uint8_t magic[8] = { 0xf8, 0x72, 0x4e, 0x1f, };
void fcpy (u8* data, int size) {
p->func(data, size, p->data);
};
pcm.magic = &magic[0];
pcm.msize = sizeof(magic);
pcm.tail = &(p->buf[offset]);
pcm.count = 6144; /* size of 32ms PCM buffer at 48kHz */
magic[4] = ai.bsmod; /* bsmod */
magic[5] = 0x01; /* None audio PCM */
magic[6] = ((ai.framesize*8) >> 8) & 0xff;
magic[7] = ((ai.framesize*8) & 0xff);
if (p->init_subids > 0)
init2pcm(&(p->buf[7]), p, ai);
else
framecpy(&(p->buf[7]), pcm, fcpy, ai, ai.framesize);
}
static inline void init2pcm(uint8_t *pts, ipack *p, const AudioInfo ai)
{
pcm_t pcm;
uint8_t magic[8] = { 0xf8, 0x72, 0x4e, 0x1f, };
# if defined(DSM_TRICK) || defined(USE_EXTENSION_STD)
int off = pts[1];
uint8_t ext_pts[2+off+4];
# endif
void fcpy (u8* data, int size) {
p->func(data, size, p->data);
};
(void)memcpy(&(ext_pts[0]), pts, 2+off);
# ifdef DSM_TRICK
ext_pts[0] |= 0x08; /* DSM trick_mode_flag */
ext_pts[1]++;
ext_pts[2+off] = 0xE0; off++; /* Reserved DSM trick mode */
# endif
# ifdef USE_EXTENSION_STD
ext_pts[0] |= 0x01; /* Set PES extension flag */
ext_pts[1] += 3;
ext_pts[2+off] = 0x10; off++; /* P-STD buffer flag (fourth bit) */
# if 1
ext_pts[2+off] = 0x40; off++; /* P-STD buffer scale factor is 0 */
ext_pts[2+off] = 0x32; off++; /* P-STD buffer size is 50*128 = 6400 byte */
# else
ext_pts[2+off] = 0x60; off++; /* P-STD buffer scale factor is 1 */
ext_pts[2+off] = 0x06; off++; /* P-STD buffer size is 6*1024 = 6144 byte */
# endif
# endif
pcm.magic = &magic[0];
pcm.msize = sizeof(magic);
pcm.tail = NULL;
pcm.count = 6144;
if (p->init_subids > 1) {
magic[4] = 7<<5; /* null frame requires stream = 7 */
magic[5] = 0x00; /* Null data_type */
magic[6] = 0x00;
magic[7] = 0x00;
} else {
magic[4] = 0x00; /* Audio ES Channel empty */
magic[5] = 0x03; /* wait for DD Decoder or pause */
magic[6] = 0x00;
magic[7] = 0x40;
}
framecpy(ext_pts, pcm, fcpy, ai, 0);
if (p->init_subids > 0)
p->init_subids--;
}
static inline void end2pcm(ipack *p)
{
pcm_t pcm;
uint8_t magic[8] = { 0xf8, 0x72, 0x4e, 0x1f, };
uint8_t pts[10] = {0x00, 0x00, };
AudioInfo ai;
# if defined(DSM_TRICK) || defined(USE_EXTENSION_STD)
int off = 0;
# endif
void fcpy (u8* data, int size) {
p->func(data, size, p->data);
};
# ifdef USE_EXTENSION_STD
pts[0] |= 0x01; /* Set PES extension flag */
pts[1] += 3;
pts[2+off] = 0x10; off++; /* P-STD buffer flag (fourth bit) */
pts[2+off] = 0x40; off++; /* P-STD buffer scale factor is 0 */
pts[2+off] = 0x10; off++; /* P-STD buffer size is 16*128 = 2048 byte */
# endif
pcm.magic = &magic[0];
pcm.msize = sizeof(magic);
pcm.tail = NULL;
pcm.count = 6144;
ai.framesize = 0;
ai.frequency = 0;
magic[4] = 0x01; /* User stop, skip or error */
magic[5] = 0x03; /* wait for DD Decoder or pause */
magic[6] = 0x00;
magic[7] = 0x40;
framecpy(pts, pcm, fcpy, ai, 0);
p->init_subids = 0;
}
void enable2pcm(ipack *p)
{
if (!p->repack_subids) {
p->repack_subids = 1;
p->init_subids = 10;
}
}
void disable2pcm(ipack *p)
{
if (p->repack_subids) {
p->repack_subids = 0;
p->init_subids = -1;
}
}
#endif /* _WARP_2_PCM_ */
------------------------------- warp2pcm.h ---------------------------
--
Info:
To unsubscribe send a mail to listar@linuxtv.org with "unsubscribe linux-dvb" as subject.
Home |
Main Index |
Thread Index