2 * dvb_demux.c - DVB kernel demux API
4 * Copyright (C) 2000-2001 Ralph Metzler <ralph@convergence.de>
5 * & Marcus Metzler <marcus@convergence.de>
6 * for convergence integrated media GmbH
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include <linux/spinlock.h>
25 #include <linux/slab.h>
26 #include <linux/vmalloc.h>
27 #include <linux/module.h>
28 #include <linux/poll.h>
29 #include <linux/string.h>
30 #include <linux/crc32.h>
31 #include <asm/uaccess.h>
33 #include "dvb_demux.h"
34 #include "dvb_functions.h"
41 int dmx_register_demux(struct dmx_demux
*demux
)
44 list_add(&demux
->reg_list
, &dmx_muxs
);
48 int dmx_unregister_demux(struct dmx_demux
* demux
)
50 struct list_head
*pos
, *n
, *head
=&dmx_muxs
;
52 list_for_each_safe (pos
, n
, head
) {
53 if (DMX_DIR_ENTRY(pos
) == demux
) {
65 struct list_head
*dmx_get_demuxes(void)
67 if (list_empty(&dmx_muxs
))
73 /******************************************************************************
74 * static inlined helper functions
75 ******************************************************************************/
78 static inline u16
section_length(const u8
*buf
)
80 return 3+((buf
[1]&0x0f)<<8)+buf
[2];
84 static inline u16
ts_pid(const u8
*buf
)
86 return ((buf
[1]&0x1f)<<8)+buf
[2];
90 static inline int payload(const u8
*tsp
)
92 if (!(tsp
[3]&0x10)) // no payload?
94 if (tsp
[3]&0x20) { // adaptation field?
95 if (tsp
[4]>183) // corrupted data?
104 void dvb_set_crc32(u8
*data
, int length
)
108 crc
= crc32_le(~0, data
, length
);
110 data
[length
] = (crc
>> 24) & 0xff;
111 data
[length
+1] = (crc
>> 16) & 0xff;
112 data
[length
+2] = (crc
>> 8) & 0xff;
113 data
[length
+3] = (crc
) & 0xff;
117 static u32
dvb_dmx_crc32 (struct dvb_demux_feed
*f
, const u8
*src
, size_t len
)
119 return (f
->feed
.sec
.crc_val
= crc32_le (f
->feed
.sec
.crc_val
, src
, len
));
123 static void dvb_dmx_memcopy (struct dvb_demux_feed
*f
, u8
*d
, const u8
*s
, size_t len
)
129 /******************************************************************************
130 * Software filter functions
131 ******************************************************************************/
133 static inline int dvb_dmx_swfilter_payload (struct dvb_demux_feed
*feed
, const u8
*buf
)
135 int count
= payload(buf
);
147 ccok=((dvbdmxfeed->cc+1)&0x0f)==cc ? 1 : 0;
150 printk("missed packet!\n");
153 if (buf
[1] & 0x40) // PUSI ?
154 feed
->peslen
= 0xfffa;
156 feed
->peslen
+= count
;
158 return feed
->cb
.ts (&buf
[p
], count
, 0, 0, &feed
->feed
.ts
, DMX_OK
);
162 static int dvb_dmx_swfilter_sectionfilter (struct dvb_demux_feed
*feed
,
163 struct dvb_demux_filter
*f
)
168 for (i
=0; i
<DVB_DEMUX_MASK_MAX
; i
++) {
169 u8
xor = f
->filter
.filter_value
[i
] ^ feed
->feed
.sec
.secbuf
[i
];
171 if (f
->maskandmode
[i
] & xor)
174 neq
|= f
->maskandnotmode
[i
] & xor;
180 return feed
->cb
.sec (feed
->feed
.sec
.secbuf
, feed
->feed
.sec
.seclen
,
181 0, 0, &f
->filter
, DMX_OK
);
185 static inline int dvb_dmx_swfilter_section_feed (struct dvb_demux_feed
*feed
)
187 struct dvb_demux
*demux
= feed
->demux
;
188 struct dvb_demux_filter
*f
= feed
->filter
;
189 struct dmx_section_feed
*sec
= &feed
->feed
.sec
;
190 u8
*buf
= sec
->secbuf
;
192 if (sec
->secbufp
!= sec
->seclen
)
195 if (!sec
->is_filtering
)
201 if (sec
->check_crc
&& demux
->check_crc32(feed
, sec
->secbuf
, sec
->seclen
))
205 if (dvb_dmx_swfilter_sectionfilter(feed
, f
) < 0)
207 } while ((f
= f
->next
) && sec
->is_filtering
);
209 sec
->secbufp
= sec
->seclen
= 0;
211 memset(buf
, 0, DVB_DEMUX_MASK_MAX
);
217 static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed
*feed
, const u8
*buf
)
219 struct dvb_demux
*demux
= feed
->demux
;
220 struct dmx_section_feed
*sec
= &feed
->feed
.sec
;
225 if (!(count
= payload(buf
)))
231 ccok
= ((feed
->cc
+1) & 0x0f) == cc
? 1 : 0;
234 if (buf
[1] & 0x40) { // PUSI set
235 // offset to start of first section is in buf[p]
236 if (p
+buf
[p
]>187) // trash if it points beyond packet
239 if (buf
[p
] && ccok
) { // rest of previous section?
240 // did we have enough data in last packet to calc length?
241 int tmp
= 3 - sec
->secbufp
;
243 if (tmp
> 0 && tmp
!= 3) {
247 demux
->memcopy (feed
, sec
->secbuf
+sec
->secbufp
,
250 sec
->seclen
= section_length(sec
->secbuf
);
252 if (sec
->seclen
> 4096)
256 rest
= sec
->seclen
- sec
->secbufp
;
258 if (rest
== buf
[p
] && sec
->seclen
) {
259 demux
->memcopy (feed
, sec
->secbuf
+ sec
->secbufp
,
261 sec
->secbufp
+= buf
[p
];
262 dvb_dmx_swfilter_section_feed(feed
);
266 p
+= buf
[p
] + 1; // skip rest of last section
273 if ((count
>2) && // enough data to determine sec length?
274 ((sec
->seclen
= section_length(buf
+p
)) <= count
)) {
275 if (sec
->seclen
>4096)
278 demux
->memcopy (feed
, sec
->secbuf
, buf
+p
,
281 sec
->secbufp
= sec
->seclen
;
285 dvb_dmx_swfilter_section_feed(feed
);
287 // filling bytes until packet end?
288 if (count
&& buf
[p
]==0xff)
291 } else { // section continues to following TS packet
292 demux
->memcopy(feed
, sec
->secbuf
, buf
+p
, count
);
301 // section continued below
305 if (!sec
->secbufp
) // any data in last ts packet?
308 // did we have enough data in last packet to calc section length?
309 if (sec
->secbufp
< 3) {
310 int tmp
= 3 - sec
->secbufp
;
317 demux
->memcopy (feed
, sec
->secbuf
+ sec
->secbufp
, buf
+p
, tmp
);
319 sec
->seclen
= section_length(sec
->secbuf
);
321 if (sec
->seclen
> 4096)
325 rest
= sec
->seclen
- sec
->secbufp
;
330 if (rest
<= count
) { // section completed in this TS packet
331 demux
->memcopy (feed
, sec
->secbuf
+ sec
->secbufp
, buf
+p
, rest
);
332 sec
->secbufp
+= rest
;
333 dvb_dmx_swfilter_section_feed(feed
);
334 } else { // section continues in following ts packet
335 demux
->memcopy (feed
, sec
->secbuf
+ sec
->secbufp
, buf
+p
, count
);
336 sec
->secbufp
+= count
;
343 static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed
*feed
, const u8
*buf
)
347 if (!feed
->feed
.ts
.is_filtering
)
349 if (feed
->ts_type
& TS_PACKET
) {
350 if (feed
->ts_type
& TS_PAYLOAD_ONLY
)
351 dvb_dmx_swfilter_payload(feed
, buf
);
353 feed
->cb
.ts(buf
, 188, 0, 0, &feed
->feed
.ts
, DMX_OK
);
355 if (feed
->ts_type
& TS_DECODER
)
356 if (feed
->demux
->write_to_decoder
)
357 feed
->demux
->write_to_decoder(feed
, buf
, 188);
361 if (!feed
->feed
.sec
.is_filtering
)
363 if (dvb_dmx_swfilter_section_packet(feed
, buf
) < 0)
364 feed
->feed
.sec
.seclen
= feed
->feed
.sec
.secbufp
=0;
373 void dvb_dmx_swfilter_packet(struct dvb_demux
*demux
, const u8
*buf
)
375 struct dvb_demux_feed
*feed
;
376 struct list_head
*pos
, *head
=&demux
->feed_list
;
377 u16 pid
= ts_pid(buf
);
379 list_for_each(pos
, head
) {
380 feed
= list_entry(pos
, struct dvb_demux_feed
, list_head
);
381 if (feed
->pid
== pid
)
382 dvb_dmx_swfilter_packet_type (feed
, buf
);
383 if (feed
->pid
== 0x2000)
384 feed
->cb
.ts(buf
, 188, 0, 0, &feed
->feed
.ts
, DMX_OK
);
389 void dvb_dmx_swfilter_packets(struct dvb_demux
*demux
, const u8
*buf
, size_t count
)
391 spin_lock(&demux
->lock
);
394 dvb_dmx_swfilter_packet(demux
, buf
);
398 spin_unlock(&demux
->lock
);
402 void dvb_dmx_swfilter(struct dvb_demux
*demux
, const u8
*buf
, size_t count
)
406 if ((i
= demux
->tsbufp
)) {
407 if (count
< (j
=188-i
)) {
408 memcpy(&demux
->tsbuf
[i
], buf
, count
);
409 demux
->tsbufp
+= count
;
412 memcpy(&demux
->tsbuf
[i
], buf
, j
);
413 dvb_dmx_swfilter_packet(demux
, demux
->tsbuf
);
419 if (buf
[p
] == 0x47) {
420 if (count
-p
>= 188) {
421 dvb_dmx_swfilter_packet(demux
, buf
+p
);
425 memcpy(demux
->tsbuf
, buf
+p
, i
);
435 static struct dvb_demux_filter
* dvb_dmx_filter_alloc(struct dvb_demux
*demux
)
439 for (i
=0; i
<demux
->filternum
; i
++)
440 if (demux
->filter
[i
].state
== DMX_STATE_FREE
)
443 if (i
== demux
->filternum
)
446 demux
->filter
[i
].state
= DMX_STATE_ALLOCATED
;
448 return &demux
->filter
[i
];
451 static struct dvb_demux_feed
* dvb_dmx_feed_alloc(struct dvb_demux
*demux
)
455 for (i
=0; i
<demux
->feednum
; i
++)
456 if (demux
->feed
[i
].state
== DMX_STATE_FREE
)
459 if (i
== demux
->feednum
)
462 demux
->feed
[i
].state
= DMX_STATE_ALLOCATED
;
464 return &demux
->feed
[i
];
468 static int dmx_pid_set (u16 pid
, struct dvb_demux_feed
*feed
)
470 struct dvb_demux
*demux
= feed
->demux
;
471 struct list_head
*pos
, *n
, *head
=&demux
->feed_list
;
473 if (pid
> DMX_MAX_PID
)
476 if (pid
== feed
->pid
)
479 if (feed
->pid
<= DMX_MAX_PID
) {
480 list_for_each_safe(pos
, n
, head
) {
481 if (DMX_FEED_ENTRY(pos
)->pid
== feed
->pid
) {
488 list_add(&feed
->list_head
, head
);
495 static int dmx_ts_feed_set (struct dmx_ts_feed
* ts_feed
, u16 pid
, int ts_type
,
496 enum dmx_ts_pes pes_type
, size_t callback_length
,
497 size_t circular_buffer_size
, int descramble
,
498 struct timespec timeout
)
500 struct dvb_demux_feed
*feed
= (struct dvb_demux_feed
*) ts_feed
;
501 struct dvb_demux
*demux
= feed
->demux
;
504 if (down_interruptible (&demux
->mutex
))
507 if (ts_type
& TS_DECODER
) {
508 if (pes_type
>= DMX_TS_PES_OTHER
) {
513 if (demux
->pesfilter
[pes_type
] &&
514 demux
->pesfilter
[pes_type
] != feed
) {
519 if ((pes_type
!= DMX_TS_PES_PCR0
) &&
520 (pes_type
!= DMX_TS_PES_PCR1
) &&
521 (pes_type
!= DMX_TS_PES_PCR2
) &&
522 (pes_type
!= DMX_TS_PES_PCR3
)) {
523 if ((ret
= dmx_pid_set(pid
, feed
))<0) {
530 demux
->pesfilter
[pes_type
] = feed
;
531 demux
->pids
[pes_type
] = feed
->pid
;
533 if ((ret
= dmx_pid_set(pid
, feed
))<0) {
539 feed
->buffer_size
= circular_buffer_size
;
540 feed
->descramble
= descramble
;
541 feed
->timeout
= timeout
;
542 feed
->cb_length
= callback_length
;
543 feed
->ts_type
= ts_type
;
544 feed
->pes_type
= pes_type
;
546 if (feed
->descramble
) {
551 if (feed
->buffer_size
) {
555 feed
->buffer
= vmalloc(feed
->buffer_size
);
563 feed
->state
= DMX_STATE_READY
;
570 static int dmx_ts_feed_start_filtering(struct dmx_ts_feed
* ts_feed
)
572 struct dvb_demux_feed
*feed
= (struct dvb_demux_feed
*) ts_feed
;
573 struct dvb_demux
*demux
= feed
->demux
;
576 if (down_interruptible (&demux
->mutex
))
579 if (feed
->state
!= DMX_STATE_READY
|| feed
->type
!= DMX_TYPE_TS
) {
584 if (!demux
->start_feed
) {
589 if ((ret
= demux
->start_feed(feed
)) < 0) {
594 spin_lock_irq(&demux
->lock
);
595 ts_feed
->is_filtering
= 1;
596 feed
->state
= DMX_STATE_GO
;
597 spin_unlock_irq(&demux
->lock
);
603 static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed
* ts_feed
)
605 struct dvb_demux_feed
*feed
= (struct dvb_demux_feed
*) ts_feed
;
606 struct dvb_demux
*demux
= feed
->demux
;
609 if (down_interruptible (&demux
->mutex
))
612 if (feed
->state
<DMX_STATE_GO
) {
617 if (!demux
->stop_feed
) {
622 ret
= demux
->stop_feed(feed
);
624 spin_lock_irq(&demux
->lock
);
625 ts_feed
->is_filtering
= 0;
626 feed
->state
= DMX_STATE_ALLOCATED
;
627 spin_unlock_irq(&demux
->lock
);
633 static int dvbdmx_allocate_ts_feed (struct dmx_demux
*dmx
, struct dmx_ts_feed
**ts_feed
,
636 struct dvb_demux
*demux
= (struct dvb_demux
*) dmx
;
637 struct dvb_demux_feed
*feed
;
639 if (down_interruptible (&demux
->mutex
))
642 if (!(feed
= dvb_dmx_feed_alloc(demux
))) {
647 feed
->type
= DMX_TYPE_TS
;
648 feed
->cb
.ts
= callback
;
651 feed
->peslen
= 0xfffa;
654 (*ts_feed
) = &feed
->feed
.ts
;
655 (*ts_feed
)->parent
= dmx
;
656 (*ts_feed
)->priv
= 0;
657 (*ts_feed
)->is_filtering
= 0;
658 (*ts_feed
)->start_filtering
= dmx_ts_feed_start_filtering
;
659 (*ts_feed
)->stop_filtering
= dmx_ts_feed_stop_filtering
;
660 (*ts_feed
)->set
= dmx_ts_feed_set
;
663 if (!(feed
->filter
= dvb_dmx_filter_alloc(demux
))) {
664 feed
->state
= DMX_STATE_FREE
;
669 feed
->filter
->type
= DMX_TYPE_TS
;
670 feed
->filter
->feed
= feed
;
671 feed
->filter
->state
= DMX_STATE_READY
;
678 static int dvbdmx_release_ts_feed(struct dmx_demux
*dmx
, struct dmx_ts_feed
*ts_feed
)
680 struct dvb_demux
*demux
= (struct dvb_demux
*) dmx
;
681 struct dvb_demux_feed
*feed
= (struct dvb_demux_feed
*) ts_feed
;
682 struct list_head
*pos
, *n
, *head
=&demux
->feed_list
;
684 if (down_interruptible (&demux
->mutex
))
687 if (feed
->state
== DMX_STATE_FREE
) {
699 feed
->state
= DMX_STATE_FREE
;
700 feed
->filter
->state
= DMX_STATE_FREE
;
702 if (feed
->pid
<= DMX_MAX_PID
) {
703 list_for_each_safe(pos
, n
, head
)
704 if (DMX_FEED_ENTRY(pos
)->pid
== feed
->pid
) {
711 if (feed
->ts_type
& TS_DECODER
)
712 demux
->pesfilter
[feed
->pes_type
] = NULL
;
719 /******************************************************************************
720 * dmx_section_feed API calls
721 ******************************************************************************/
723 static int dmx_section_feed_allocate_filter(struct dmx_section_feed
* feed
,
724 struct dmx_section_filter
** filter
)
726 struct dvb_demux_feed
*dvbdmxfeed
=(struct dvb_demux_feed
*) feed
;
727 struct dvb_demux
*dvbdemux
=dvbdmxfeed
->demux
;
728 struct dvb_demux_filter
*dvbdmxfilter
;
730 if (down_interruptible (&dvbdemux
->mutex
))
733 dvbdmxfilter
=dvb_dmx_filter_alloc(dvbdemux
);
735 up(&dvbdemux
->mutex
);
739 spin_lock_irq(&dvbdemux
->lock
);
740 *filter
=&dvbdmxfilter
->filter
;
741 (*filter
)->parent
=feed
;
743 dvbdmxfilter
->feed
=dvbdmxfeed
;
744 dvbdmxfilter
->type
=DMX_TYPE_SEC
;
745 dvbdmxfilter
->state
=DMX_STATE_READY
;
747 dvbdmxfilter
->next
=dvbdmxfeed
->filter
;
748 dvbdmxfeed
->filter
=dvbdmxfilter
;
749 spin_unlock_irq(&dvbdemux
->lock
);
750 up(&dvbdemux
->mutex
);
755 static int dmx_section_feed_set(struct dmx_section_feed
* feed
,
756 u16 pid
, size_t circular_buffer_size
,
757 int descramble
, int check_crc
)
759 struct dvb_demux_feed
*dvbdmxfeed
=(struct dvb_demux_feed
*) feed
;
760 struct dvb_demux
*dvbdmx
=dvbdmxfeed
->demux
;
761 struct list_head
*pos
, *n
, *head
=&dvbdmx
->feed_list
;
766 if (down_interruptible (&dvbdmx
->mutex
))
769 if (dvbdmxfeed
->pid
<= DMX_MAX_PID
) {
770 list_for_each_safe(pos
, n
, head
) {
771 if (DMX_FEED_ENTRY(pos
)->pid
== dvbdmxfeed
->pid
) {
778 list_add(&dvbdmxfeed
->list_head
, head
);
780 dvbdmxfeed
->pid
= pid
;
781 dvbdmxfeed
->buffer_size
=circular_buffer_size
;
782 dvbdmxfeed
->descramble
=descramble
;
783 if (dvbdmxfeed
->descramble
) {
788 dvbdmxfeed
->feed
.sec
.check_crc
=check_crc
;
790 dvbdmxfeed
->buffer
=0;
792 dvbdmxfeed
->buffer
=vmalloc(dvbdmxfeed
->buffer_size
);
793 if (!dvbdmxfeed
->buffer
) {
798 dvbdmxfeed
->state
=DMX_STATE_READY
;
803 static void prepare_secfilters(struct dvb_demux_feed
*dvbdmxfeed
)
806 struct dvb_demux_filter
*f
;
807 struct dmx_section_filter
*sf
;
808 u8 mask
, mode
, doneq
;
810 if (!(f
=dvbdmxfeed
->filter
))
815 for (i
=0; i
<DVB_DEMUX_MASK_MAX
; i
++) {
816 mode
=sf
->filter_mode
[i
];
817 mask
=sf
->filter_mask
[i
];
818 f
->maskandmode
[i
]=mask
&mode
;
819 doneq
|=f
->maskandnotmode
[i
]=mask
&~mode
;
821 f
->doneq
=doneq
? 1 : 0;
822 } while ((f
=f
->next
));
826 static int dmx_section_feed_start_filtering(struct dmx_section_feed
*feed
)
828 struct dvb_demux_feed
*dvbdmxfeed
=(struct dvb_demux_feed
*) feed
;
829 struct dvb_demux
*dvbdmx
=dvbdmxfeed
->demux
;
832 if (down_interruptible (&dvbdmx
->mutex
))
835 if (feed
->is_filtering
) {
839 if (!dvbdmxfeed
->filter
) {
843 dvbdmxfeed
->feed
.sec
.secbufp
=0;
844 dvbdmxfeed
->feed
.sec
.seclen
=0;
846 if (!dvbdmx
->start_feed
) {
851 prepare_secfilters(dvbdmxfeed
);
853 if ((ret
= dvbdmx
->start_feed(dvbdmxfeed
)) < 0) {
858 spin_lock_irq(&dvbdmx
->lock
);
859 feed
->is_filtering
=1;
860 dvbdmxfeed
->state
=DMX_STATE_GO
;
861 spin_unlock_irq(&dvbdmx
->lock
);
867 static int dmx_section_feed_stop_filtering(struct dmx_section_feed
* feed
)
869 struct dvb_demux_feed
*dvbdmxfeed
=(struct dvb_demux_feed
*) feed
;
870 struct dvb_demux
*dvbdmx
=dvbdmxfeed
->demux
;
873 if (down_interruptible (&dvbdmx
->mutex
))
876 if (!dvbdmx
->stop_feed
) {
880 ret
=dvbdmx
->stop_feed(dvbdmxfeed
);
881 spin_lock_irq(&dvbdmx
->lock
);
882 dvbdmxfeed
->state
=DMX_STATE_READY
;
883 feed
->is_filtering
=0;
884 spin_unlock_irq(&dvbdmx
->lock
);
890 static int dmx_section_feed_release_filter(struct dmx_section_feed
*feed
,
891 struct dmx_section_filter
* filter
)
893 struct dvb_demux_filter
*dvbdmxfilter
=(struct dvb_demux_filter
*) filter
, *f
;
894 struct dvb_demux_feed
*dvbdmxfeed
=(struct dvb_demux_feed
*) feed
;
895 struct dvb_demux
*dvbdmx
=dvbdmxfeed
->demux
;
897 if (down_interruptible (&dvbdmx
->mutex
))
900 if (dvbdmxfilter
->feed
!=dvbdmxfeed
) {
904 if (feed
->is_filtering
)
905 feed
->stop_filtering(feed
);
907 spin_lock_irq(&dvbdmx
->lock
);
908 f
=dvbdmxfeed
->filter
;
910 if (f
== dvbdmxfilter
) {
911 dvbdmxfeed
->filter
=dvbdmxfilter
->next
;
913 while(f
->next
!=dvbdmxfilter
)
915 f
->next
=f
->next
->next
;
917 dvbdmxfilter
->state
=DMX_STATE_FREE
;
918 spin_unlock_irq(&dvbdmx
->lock
);
923 static int dvbdmx_allocate_section_feed(struct dmx_demux
*demux
,
924 struct dmx_section_feed
**feed
,
925 dmx_section_cb callback
)
927 struct dvb_demux
*dvbdmx
=(struct dvb_demux
*) demux
;
928 struct dvb_demux_feed
*dvbdmxfeed
;
930 if (down_interruptible (&dvbdmx
->mutex
))
933 if (!(dvbdmxfeed
=dvb_dmx_feed_alloc(dvbdmx
))) {
937 dvbdmxfeed
->type
=DMX_TYPE_SEC
;
938 dvbdmxfeed
->cb
.sec
=callback
;
939 dvbdmxfeed
->demux
=dvbdmx
;
940 dvbdmxfeed
->pid
=0xffff;
941 dvbdmxfeed
->feed
.sec
.secbufp
=0;
942 dvbdmxfeed
->filter
=0;
943 dvbdmxfeed
->buffer
=0;
945 (*feed
)=&dvbdmxfeed
->feed
.sec
;
946 (*feed
)->is_filtering
=0;
947 (*feed
)->parent
=demux
;
950 (*feed
)->set
=dmx_section_feed_set
;
951 (*feed
)->allocate_filter
=dmx_section_feed_allocate_filter
;
952 (*feed
)->start_filtering
=dmx_section_feed_start_filtering
;
953 (*feed
)->stop_filtering
=dmx_section_feed_stop_filtering
;
954 (*feed
)->release_filter
= dmx_section_feed_release_filter
;
960 static int dvbdmx_release_section_feed(struct dmx_demux
*demux
,
961 struct dmx_section_feed
*feed
)
963 struct dvb_demux_feed
*dvbdmxfeed
=(struct dvb_demux_feed
*) feed
;
964 struct dvb_demux
*dvbdmx
=(struct dvb_demux
*) demux
;
965 struct list_head
*pos
, *n
, *head
=&dvbdmx
->feed_list
;
967 if (down_interruptible (&dvbdmx
->mutex
))
970 if (dvbdmxfeed
->state
==DMX_STATE_FREE
) {
975 if (dvbdmxfeed
->buffer
) {
976 vfree(dvbdmxfeed
->buffer
);
977 dvbdmxfeed
->buffer
=0;
980 dvbdmxfeed
->state
=DMX_STATE_FREE
;
982 if (dvbdmxfeed
->pid
<= DMX_MAX_PID
) {
983 list_for_each_safe(pos
, n
, head
) {
984 if (DMX_FEED_ENTRY(pos
)->pid
== dvbdmxfeed
->pid
) {
989 dvbdmxfeed
->pid
= 0xffff;
997 /******************************************************************************
998 * dvb_demux kernel data API calls
999 ******************************************************************************/
1001 static int dvbdmx_open(struct dmx_demux
*demux
)
1003 struct dvb_demux
*dvbdemux
=(struct dvb_demux
*) demux
;
1005 if (dvbdemux
->users
>=MAX_DVB_DEMUX_USERS
)
1012 static int dvbdmx_close(struct dmx_demux
*demux
)
1014 struct dvb_demux
*dvbdemux
=(struct dvb_demux
*) demux
;
1016 if (dvbdemux
->users
==0)
1019 //FIXME: release any unneeded resources if users==0
1024 static int dvbdmx_write(struct dmx_demux
*demux
, const char *buf
, size_t count
)
1026 struct dvb_demux
*dvbdemux
=(struct dvb_demux
*) demux
;
1028 if ((!demux
->frontend
) || (demux
->frontend
->source
!= DMX_MEMORY_FE
))
1031 if (down_interruptible (&dvbdemux
->mutex
))
1032 return -ERESTARTSYS
;
1034 dvb_dmx_swfilter(dvbdemux
, buf
, count
);
1035 up(&dvbdemux
->mutex
);
1040 static int dvbdmx_add_frontend(struct dmx_demux
*demux
, struct dmx_frontend
*frontend
)
1042 struct dvb_demux
*dvbdemux
=(struct dvb_demux
*) demux
;
1043 struct list_head
*head
= &dvbdemux
->frontend_list
;
1045 list_add(&(frontend
->connectivity_list
), head
);
1051 static int dvbdmx_remove_frontend(struct dmx_demux
*demux
, struct dmx_frontend
*frontend
)
1053 struct dvb_demux
*dvbdemux
=(struct dvb_demux
*) demux
;
1054 struct list_head
*pos
, *n
, *head
=&dvbdemux
->frontend_list
;
1056 list_for_each_safe (pos
, n
, head
) {
1057 if (DMX_FE_ENTRY(pos
) == frontend
) {
1066 static struct list_head
* dvbdmx_get_frontends(struct dmx_demux
*demux
)
1068 struct dvb_demux
*dvbdemux
=(struct dvb_demux
*) demux
;
1070 if (list_empty(&dvbdemux
->frontend_list
))
1072 return &dvbdemux
->frontend_list
;
1076 int dvbdmx_connect_frontend(struct dmx_demux
*demux
, struct dmx_frontend
*frontend
)
1078 struct dvb_demux
*dvbdemux
=(struct dvb_demux
*) demux
;
1080 if (demux
->frontend
)
1083 if (down_interruptible (&dvbdemux
->mutex
))
1084 return -ERESTARTSYS
;
1086 demux
->frontend
=frontend
;
1087 up(&dvbdemux
->mutex
);
1092 int dvbdmx_disconnect_frontend(struct dmx_demux
*demux
)
1094 struct dvb_demux
*dvbdemux
=(struct dvb_demux
*) demux
;
1096 if (down_interruptible (&dvbdemux
->mutex
))
1097 return -ERESTARTSYS
;
1099 demux
->frontend
=NULL
;
1100 up(&dvbdemux
->mutex
);
1105 static int dvbdmx_get_pes_pids(struct dmx_demux
*demux
, u16
*pids
)
1107 struct dvb_demux
*dvbdemux
=(struct dvb_demux
*) demux
;
1109 memcpy(pids
, dvbdemux
->pids
, 5*sizeof(u16
));
1114 dvb_dmx_init(struct dvb_demux
*dvbdemux
)
1117 struct dmx_demux
*dmx
= &dvbdemux
->dmx
;
1120 dvbdemux
->filter
=vmalloc(dvbdemux
->filternum
*sizeof(struct dvb_demux_filter
));
1121 if (!dvbdemux
->filter
)
1124 dvbdemux
->feed
=vmalloc(dvbdemux
->feednum
*sizeof(struct dvb_demux_feed
));
1125 if (!dvbdemux
->feed
) {
1126 vfree(dvbdemux
->filter
);
1129 for (i
=0; i
<dvbdemux
->filternum
; i
++) {
1130 dvbdemux
->filter
[i
].state
=DMX_STATE_FREE
;
1131 dvbdemux
->filter
[i
].index
=i
;
1133 for (i
=0; i
<dvbdemux
->feednum
; i
++)
1134 dvbdemux
->feed
[i
].state
=DMX_STATE_FREE
;
1135 dvbdemux
->frontend_list
.next
=
1136 dvbdemux
->frontend_list
.prev
=
1137 &dvbdemux
->frontend_list
;
1138 for (i
=0; i
<DMX_TS_PES_OTHER
; i
++) {
1139 dvbdemux
->pesfilter
[i
]=NULL
;
1140 dvbdemux
->pids
[i
]=0xffff;
1143 INIT_LIST_HEAD(&dvbdemux
->feed_list
);
1145 dvbdemux
->playing
= 0;
1146 dvbdemux
->recording
= 0;
1149 if (!dvbdemux
->check_crc32
)
1150 dvbdemux
->check_crc32
= dvb_dmx_crc32
;
1152 if (!dvbdemux
->memcopy
)
1153 dvbdemux
->memcopy
= dvb_dmx_memcopy
;
1156 dmx
->reg_list
.prev
= dmx
->reg_list
.next
= &dmx
->reg_list
;
1157 dmx
->priv
=(void *) dvbdemux
;
1158 dmx
->open
=dvbdmx_open
;
1159 dmx
->close
=dvbdmx_close
;
1160 dmx
->write
=dvbdmx_write
;
1161 dmx
->allocate_ts_feed
=dvbdmx_allocate_ts_feed
;
1162 dmx
->release_ts_feed
=dvbdmx_release_ts_feed
;
1163 dmx
->allocate_section_feed
=dvbdmx_allocate_section_feed
;
1164 dmx
->release_section_feed
=dvbdmx_release_section_feed
;
1166 dmx
->descramble_mac_address
=NULL
;
1167 dmx
->descramble_section_payload
=NULL
;
1169 dmx
->add_frontend
=dvbdmx_add_frontend
;
1170 dmx
->remove_frontend
=dvbdmx_remove_frontend
;
1171 dmx
->get_frontends
=dvbdmx_get_frontends
;
1172 dmx
->connect_frontend
=dvbdmx_connect_frontend
;
1173 dmx
->disconnect_frontend
=dvbdmx_disconnect_frontend
;
1174 dmx
->get_pes_pids
=dvbdmx_get_pes_pids
;
1175 sema_init(&dvbdemux
->mutex
, 1);
1176 spin_lock_init(&dvbdemux
->lock
);
1178 if ((err
= dmx_register_demux(dmx
)) < 0)
1185 dvb_dmx_release(struct dvb_demux
*dvbdemux
)
1187 struct dmx_demux
*dmx
= &dvbdemux
->dmx
;
1189 dmx_unregister_demux(dmx
);
1190 if (dvbdemux
->filter
)
1191 vfree(dvbdemux
->filter
);
1193 vfree(dvbdemux
->feed
);