111
|
1 /* { dg-options "-mlong-calls" { target mips*-*-* } } */
|
|
2
|
|
3 typedef unsigned char u8;
|
|
4 typedef unsigned short u16;
|
|
5 typedef unsigned int __kernel_size_t;
|
|
6 typedef __kernel_size_t size_t;
|
|
7 struct list_head {
|
|
8 struct list_head *next;
|
|
9 };
|
|
10
|
|
11 struct dmx_ts_feed {
|
|
12 int is_filtering;
|
|
13 };
|
|
14 struct dmx_section_feed {
|
|
15 u16 secbufp;
|
|
16 u16 seclen;
|
|
17 u16 tsfeedp;
|
|
18 };
|
|
19
|
|
20 typedef int (*dmx_ts_cb) (
|
|
21 const u8 * buffer1,
|
|
22 size_t buffer1_length,
|
|
23 const u8 * buffer2,
|
|
24 size_t buffer2_length
|
|
25 );
|
|
26
|
|
27 struct dvb_demux_feed {
|
|
28 union {
|
|
29 struct dmx_ts_feed ts;
|
|
30 struct dmx_section_feed sec;
|
|
31 } feed;
|
|
32 union {
|
|
33 dmx_ts_cb ts;
|
|
34 } cb;
|
|
35 int type;
|
|
36 u16 pid;
|
|
37 int ts_type;
|
|
38 struct list_head list_head;
|
|
39 };
|
|
40
|
|
41 struct dvb_demux {
|
|
42 int (*stop_feed)(struct dvb_demux_feed *feed);
|
|
43 struct list_head feed_list;
|
|
44 };
|
|
45
|
|
46 int dvb_dmx_swfilter_section_packet (struct dvb_demux_feed *, const u8 *);
|
|
47
|
|
48 static
|
|
49 inline
|
|
50 __attribute__((always_inline))
|
|
51 u8
|
|
52 payload(const u8 *tsp)
|
|
53 {
|
|
54 if (tsp[3] & 0x20) {
|
|
55 return 184 - 1 - tsp[4];
|
|
56 }
|
|
57 return 184;
|
|
58 }
|
|
59
|
|
60 static
|
|
61 inline
|
|
62 __attribute__((always_inline))
|
|
63 int
|
|
64 dvb_dmx_swfilter_payload(struct dvb_demux_feed *feed, const u8 *buf)
|
|
65 {
|
|
66 int count = payload(buf);
|
|
67 int p;
|
|
68 if (count == 0)
|
|
69 return -1;
|
|
70 return feed->cb.ts(&buf[p], count, ((void *)0), 0);
|
|
71 }
|
|
72
|
|
73 static
|
|
74 inline
|
|
75 __attribute__((always_inline))
|
|
76 void
|
|
77 dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed, const u8 *buf)
|
|
78 {
|
|
79 switch (feed->type) {
|
|
80 case 0:
|
|
81 if (feed->ts_type & 1) {
|
|
82 dvb_dmx_swfilter_payload(feed, buf);
|
|
83 }
|
|
84 if (dvb_dmx_swfilter_section_packet(feed, buf) < 0)
|
|
85 feed->feed.sec.seclen = feed->feed.sec.secbufp = 0;
|
|
86 }
|
|
87 }
|
|
88
|
|
89 static
|
|
90 void
|
|
91 dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
|
|
92 {
|
|
93 struct dvb_demux_feed *feed;
|
|
94 int dvr_done = 0;
|
|
95
|
|
96 for (feed = ({ const typeof( ((typeof(*feed) *)0)->list_head ) *__mptr = ((&demux->feed_list)->next); (typeof(*feed) *)( (char *)__mptr - __builtin_offsetof(typeof(*feed),list_head) );}); __builtin_prefetch(feed->list_head.next), &feed->list_head != (&demux->feed_list); feed = ({ const typeof( ((typeof(*feed) *)0)->list_head ) *__mptr = (feed->list_head.next); (typeof(*feed) *)( (char *)__mptr - __builtin_offsetof(typeof(*feed),list_head) );})) {
|
|
97 if (((((feed)->type == 0) && ((feed)->feed.ts.is_filtering) && (((feed)->ts_type & (1 | 8)) == 1))) && (dvr_done++))
|
|
98 dvb_dmx_swfilter_packet_type(feed, buf);
|
|
99 else if (feed->pid == 0x2000)
|
|
100 feed->cb.ts(buf, 188, ((void *)0), 0);
|
|
101 }
|
|
102 }
|
|
103 void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, size_t count)
|
|
104 {
|
|
105 while (count--) {
|
|
106 dvb_dmx_swfilter_packet(demux, buf);
|
|
107 }
|
|
108 }
|