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
payload(const u8 * tsp)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
dvb_dmx_swfilter_payload(struct dvb_demux_feed * feed,const u8 * buf)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
dvb_dmx_swfilter_packet_type(struct dvb_demux_feed * feed,const u8 * buf)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
dvb_dmx_swfilter_packet(struct dvb_demux * demux,const u8 * buf)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 }
dvb_dmx_swfilter_packets(struct dvb_demux * demux,const u8 * buf,size_t count)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 }
109