]> git.sesse.net Git - vlc/blob - include/input_netlist.h
4e1c8b5ccf73ebfbf841fcecd7cfd632dd9cd7b7
[vlc] / include / input_netlist.h
1 /*****************************************************************************
2  * input_netlist.h: netlist interface
3  * (c)1998 VideoLAN
4  *****************************************************************************
5  * The netlists are an essential part of the input structure. We maintain a
6  * list of free TS packets and free PES packets to avoid continuous malloc
7  * and free.
8  *****************************************************************************/
9
10 #include "intf_msg.h"
11
12 /*****************************************************************************
13  * Prototypes
14  *****************************************************************************/
15 int     input_NetlistInit       ( input_thread_t *p_input );
16 void    input_NetlistEnd        ( input_thread_t *p_input );
17
18 static __inline__ void input_NetlistFreePES( input_thread_t *p_input, pes_packet_t *p_pes_packet );
19 static __inline__ void input_NetlistFreeTS( input_thread_t *p_input, ts_packet_t *p_ts_packet );
20 static __inline__ pes_packet_t* input_NetlistGetPES( input_thread_t *p_input );
21
22 /*****************************************************************************
23  * input_NetlistFreePES: add a PES packet to the netlist
24  *****************************************************************************
25  * Add a PES packet to the PES netlist, so that the packet can immediately be
26  * reused by the demultiplexer. We put this function directly in the .h file,
27  * because it is very frequently called.
28  *****************************************************************************/
29 static __inline__ void input_NetlistFreePES( input_thread_t *p_input,
30                                   pes_packet_t *p_pes_packet )
31 {
32     int             i_dummy;
33     ts_packet_t *   p_ts_packet;
34
35     ASSERT(p_pes_packet);
36
37     /* We will be playing with indexes, so we take a lock. */
38     vlc_mutex_lock( &p_input->netlist.lock );
39
40     /* Free all TS packets in this PES structure. */
41     p_ts_packet = p_pes_packet->p_first_ts;
42     for( i_dummy = 0; i_dummy < p_pes_packet->i_ts_packets; i_dummy++ )
43     {
44         ASSERT(p_ts_packet);
45
46 #ifdef INPUT_LIFO_TS_NETLIST
47         p_input->netlist.i_ts_index--;
48         p_input->netlist.p_ts_free[p_input->netlist.i_ts_index].iov_base
49                              = p_ts_packet;
50 #else /* FIFO */
51         p_input->netlist.p_ts_free[p_input->netlist.i_ts_end].iov_base
52                              = p_ts_packet;
53         p_input->netlist.i_ts_end++;
54         p_input->netlist.i_ts_end &= INPUT_MAX_TS; /* loop */
55 #endif
56         p_ts_packet = p_ts_packet->p_next_ts;
57     }
58
59     /* Free the PES structure. */
60 #ifdef INPUT_LIFO_PES_NETLIST
61     p_input->netlist.i_pes_index--;
62     p_input->netlist.p_pes_free[p_input->netlist.i_pes_index] = p_pes_packet;
63 #else /* FIFO */
64     p_input->netlist.p_pes_free[p_input->netlist.i_pes_end] = p_pes_packet;
65     p_input->netlist.i_pes_end++;
66     p_input->netlist.i_pes_end &= INPUT_MAX_PES; /* loop */
67 #endif
68
69     vlc_mutex_unlock( &p_input->netlist.lock );
70 }
71
72 /*****************************************************************************
73  * input_NetlistFreeTS: add a TS packet to the netlist
74  *****************************************************************************
75  * Add a TS packet to the TS netlist, so that the packet can immediately be
76  * reused by the demultiplexer. Shouldn't be called by other threads (they
77  * should only use input_FreePES.
78  *****************************************************************************/
79 static __inline__ void input_NetlistFreeTS( input_thread_t *p_input,
80                                             ts_packet_t *p_ts_packet )
81 {
82     ASSERT(p_ts_packet);
83
84     /* We will be playing with indexes, so we take a lock. */
85     vlc_mutex_lock( &p_input->netlist.lock );
86
87     /* Free the TS structure. */
88 #ifdef INPUT_LIFO_TS_NETLIST
89     p_input->netlist.i_ts_index--;
90     p_input->netlist.p_ts_free[p_input->netlist.i_ts_index].iov_base = p_ts_packet;
91 #else /* FIFO */
92     p_input->netlist.p_ts_free[p_input->netlist.i_ts_end].iov_base = p_ts_packet;
93     p_input->netlist.i_ts_end++;
94     p_input->netlist.i_ts_end &= INPUT_MAX_TS; /* loop */
95 #endif
96
97     vlc_mutex_unlock( &p_input->netlist.lock );
98 }
99
100 /*****************************************************************************
101  * input_NetlistGetPES: remove a PES packet from the netlist
102  *****************************************************************************
103  * Add a TS packet to the TS netlist, so that the packet can immediately be
104  * reused by the demultiplexer. Shouldn't be called by other threads (they
105  * should only use input_FreePES.
106  *****************************************************************************/
107 static __inline__ pes_packet_t* input_NetlistGetPES( input_thread_t *p_input )
108 {
109     pes_packet_t *          p_pes_packet;
110
111 #ifdef INPUT_LIFO_PES_NETLIST
112     /* i_pes_index might be accessed by a decoder thread to give back a
113      * packet. */
114     vlc_mutex_lock( &p_input->netlist.lock );
115
116     /* Verify that we still have PES packet in the netlist */
117     if( (INPUT_MAX_PES - p_input->netlist.i_pes_index ) <= 1 )
118     {
119         intf_ErrMsg("input error: PES netlist is empty !\n");
120         return( NULL );
121     }
122
123     /* Fetch a new PES packet */
124     p_pes_packet = p_input->netlist.p_pes_free[p_input->netlist.i_pes_index];
125     p_input->netlist.i_pes_index++;
126     vlc_mutex_unlock( &p_input->netlist.lock );
127
128 #else /* FIFO */
129     /* No need to lock, since we are the only ones accessing i_pes_start. */
130
131     /* Verify that we still have PES packet in the netlist */
132     if( ((p_input->netlist.i_pes_end -1 - p_input->netlist.i_pes_start) & INPUT_MAX_PES) <= 1 )
133     {
134         intf_ErrMsg("input error: PES netlist is empty !\n");
135         return( NULL );
136     }
137
138     p_pes_packet = p_input->netlist.p_pes_free[p_input->netlist.i_pes_start];
139     p_input->netlist.i_pes_start++;
140     p_input->netlist.i_pes_start &= INPUT_MAX_PES; /* loop */
141 #endif /* netlist type */
142
143     /* Initialize PES flags. */
144     p_pes_packet->b_data_loss = 0;
145     p_pes_packet->b_data_alignment = 0;
146     p_pes_packet->b_has_pts = 0;
147     p_pes_packet->b_random_access = 0;
148     p_pes_packet->b_discard_payload = 0;
149     p_pes_packet->i_pes_size = 0;
150     p_pes_packet->i_ts_packets = 0;
151     p_pes_packet->p_first_ts = NULL;
152     p_pes_packet->p_last_ts = NULL;
153
154     return( p_pes_packet );
155 }