1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
|
/*
* demux.h
*
* Copyright (c) 2002 Convergence GmbH
*
* based on code:
* Copyright (c) 2000 Nokia Research Center
* Tampere, FINLAND
*
* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifndef __DEMUX_H
#define __DEMUX_H
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/list.h>
#include <linux/time.h>
#include <linux/dvb/dmx.h>
/*--------------------------------------------------------------------------*/
/* Common definitions */
/*--------------------------------------------------------------------------*/
#define DMX_EVENT_QUEUE_SIZE 500 /* number of events */
/*
* DMX_MAX_FILTER_SIZE: Maximum length (in bytes) of a section/PES filter.
*/
#ifndef DMX_MAX_FILTER_SIZE
#define DMX_MAX_FILTER_SIZE 18
#endif
/*
* DMX_MAX_SECFEED_SIZE: Maximum length (in bytes) of a private section feed filter.
*/
#ifndef DMX_MAX_SECTION_SIZE
#define DMX_MAX_SECTION_SIZE 4096
#endif
#ifndef DMX_MAX_SECFEED_SIZE
#define DMX_MAX_SECFEED_SIZE (DMX_MAX_SECTION_SIZE + 188)
#endif
/*
* enum dmx_success: Success codes for the Demux Callback API.
*/
enum dmx_success {
DMX_OK = 0, /* Received Ok */
DMX_OK_PES_END, /* Received OK, data reached end of PES packet */
DMX_OK_PCR, /* Received OK, data with new PCR/STC pair */
DMX_OK_EOS, /* Received OK, reached End-of-Stream (EOS) */
DMX_OK_MARKER, /* Received OK, reached a data Marker */
DMX_LENGTH_ERROR, /* Incorrect length */
DMX_OVERRUN_ERROR, /* Receiver ring buffer overrun */
DMX_CRC_ERROR, /* Incorrect CRC */
DMX_FRAME_ERROR, /* Frame alignment error */
DMX_FIFO_ERROR, /* Receiver FIFO overrun */
DMX_MISSED_ERROR, /* Receiver missed packet */
DMX_OK_DECODER_BUF, /* Received OK, new ES data in decoder buffer */
DMX_OK_IDX, /* Received OK, new index event */
DMX_OK_SCRAMBLING_STATUS, /* Received OK, new scrambling status */
};
/*
* struct dmx_data_ready: Parameters for event notification callback.
* Event notification notifies demux device that data is written
* and available in the device's output buffer or provides
* notification on errors and other events. In the latter case
* data_length is zero.
*/
struct dmx_data_ready {
enum dmx_success status;
/*
* data_length may be 0 in case of DMX_OK_PES_END or DMX_OK_EOS
* and in non-DMX_OK_XXX events. In DMX_OK_PES_END,
* data_length is for data coming after the end of PES.
*/
int data_length;
union {
struct {
int start_gap;
int actual_length;
int disc_indicator_set;
int pes_length_mismatch;
u64 stc;
u32 tei_counter;
u32 cont_err_counter;
u32 ts_packets_num;
} pes_end;
struct {
u64 pcr;
u64 stc;
int disc_indicator_set;
} pcr;
struct {
int handle;
int cookie;
u32 offset;
u32 len;
int pts_exists;
u64 pts;
int dts_exists;
u64 dts;
u32 tei_counter;
u32 cont_err_counter;
u32 ts_packets_num;
u32 ts_dropped_bytes;
u64 stc;
} buf;
struct {
u64 id;
} marker;
struct dmx_index_event_info idx_event;
struct dmx_scrambling_status_event_info scrambling_bits;
};
};
/*
* struct data_buffer: Parameters of buffer allocated by
* demux device for input/output. Can be used to directly map the
* demux-device buffer to HW output if HW supports it.
*/
struct data_buffer {
/* dvb_ringbuffer managed by demux-device */
const struct dvb_ringbuffer *ringbuff;
/*
* Private handle returned by kernel demux when
* map_buffer is called in case external buffer
* is used. NULL if buffer is allocated internally.
*/
void *priv_handle;
};
/*--------------------------------------------------------------------------*/
/* TS packet reception */
/*--------------------------------------------------------------------------*/
/* TS filter type for set() */
#define TS_PACKET 1 /* send TS packets (188 bytes) to callback (default) */
#define TS_PAYLOAD_ONLY 2 /* in case TS_PACKET is set, only send the TS
payload (<=184 bytes per packet) to callback */
#define TS_DECODER 4 /* send stream to built-in decoder (if present) */
#define TS_DEMUX 8 /* in case TS_PACKET is set, send the TS to
the demux device, not to the dvr device */
struct dmx_ts_feed;
typedef int (*dmx_ts_data_ready_cb)(
struct dmx_ts_feed *source,
struct dmx_data_ready *dmx_data_ready);
struct dmx_ts_feed {
int is_filtering; /* Set to non-zero when filtering in progress */
struct dmx_demux *parent; /* Back-pointer */
struct data_buffer buffer;
void *priv; /* Pointer to private data of the API client */
struct dmx_decoder_buffers *decoder_buffers;
int (*set) (struct dmx_ts_feed *feed,
u16 pid,
int type,
enum dmx_ts_pes pes_type,
size_t circular_buffer_size,
struct timespec timeout);
int (*start_filtering) (struct dmx_ts_feed* feed);
int (*stop_filtering) (struct dmx_ts_feed* feed);
int (*set_video_codec) (struct dmx_ts_feed *feed,
enum dmx_video_codec video_codec);
int (*set_idx_params) (struct dmx_ts_feed *feed,
struct dmx_indexing_params *idx_params);
int (*get_decoder_buff_status)(
struct dmx_ts_feed *feed,
struct dmx_buffer_status *dmx_buffer_status);
int (*reuse_decoder_buffer)(
struct dmx_ts_feed *feed,
int cookie);
int (*data_ready_cb)(struct dmx_ts_feed *feed,
dmx_ts_data_ready_cb callback);
int (*notify_data_read)(struct dmx_ts_feed *feed,
u32 bytes_num);
int (*set_tsp_out_format)(struct dmx_ts_feed *feed,
enum dmx_tsp_format_t tsp_format);
int (*set_secure_mode)(struct dmx_ts_feed *feed,
struct dmx_secure_mode *sec_mode);
int (*set_cipher_ops)(struct dmx_ts_feed *feed,
struct dmx_cipher_operations *cipher_ops);
int (*oob_command) (struct dmx_ts_feed *feed,
struct dmx_oob_command *cmd);
int (*ts_insertion_init)(struct dmx_ts_feed *feed);
int (*ts_insertion_terminate)(struct dmx_ts_feed *feed);
int (*ts_insertion_insert_buffer)(struct dmx_ts_feed *feed,
char *data, size_t size);
int (*get_scrambling_bits)(struct dmx_ts_feed *feed, u8 *value);
int (*flush_buffer)(struct dmx_ts_feed *feed, size_t length);
};
/*--------------------------------------------------------------------------*/
/* Section reception */
/*--------------------------------------------------------------------------*/
struct dmx_section_filter {
u8 filter_value [DMX_MAX_FILTER_SIZE];
u8 filter_mask [DMX_MAX_FILTER_SIZE];
u8 filter_mode [DMX_MAX_FILTER_SIZE];
struct dmx_section_feed* parent; /* Back-pointer */
struct data_buffer buffer;
void* priv; /* Pointer to private data of the API client */
};
struct dmx_section_feed;
typedef int (*dmx_section_data_ready_cb)(
struct dmx_section_filter *source,
struct dmx_data_ready *dmx_data_ready);
struct dmx_section_feed {
int is_filtering; /* Set to non-zero when filtering in progress */
struct dmx_demux* parent; /* Back-pointer */
void* priv; /* Pointer to private data of the API client */
int check_crc;
u32 crc_val;
u8 *secbuf;
u8 secbuf_base[DMX_MAX_SECFEED_SIZE];
u16 secbufp, seclen, tsfeedp;
int (*set) (struct dmx_section_feed* feed,
u16 pid,
size_t circular_buffer_size,
int check_crc);
int (*allocate_filter) (struct dmx_section_feed* feed,
struct dmx_section_filter** filter);
int (*release_filter) (struct dmx_section_feed* feed,
struct dmx_section_filter* filter);
int (*start_filtering) (struct dmx_section_feed* feed);
int (*stop_filtering) (struct dmx_section_feed* feed);
int (*data_ready_cb)(struct dmx_section_feed *feed,
dmx_section_data_ready_cb callback);
int (*notify_data_read)(struct dmx_section_filter *filter,
u32 bytes_num);
int (*set_secure_mode)(struct dmx_section_feed *feed,
struct dmx_secure_mode *sec_mode);
int (*set_cipher_ops)(struct dmx_section_feed *feed,
struct dmx_cipher_operations *cipher_ops);
int (*oob_command) (struct dmx_section_feed *feed,
struct dmx_oob_command *cmd);
int (*get_scrambling_bits)(struct dmx_section_feed *feed, u8 *value);
int (*flush_buffer)(struct dmx_section_feed *feed, size_t length);
};
/*--------------------------------------------------------------------------*/
/* Callback functions */
/*--------------------------------------------------------------------------*/
typedef int (*dmx_ts_cb) ( const u8 * buffer1,
size_t buffer1_length,
const u8 * buffer2,
size_t buffer2_length,
struct dmx_ts_feed* source,
enum dmx_success success);
typedef int (*dmx_section_cb) ( const u8 * buffer1,
size_t buffer1_len,
const u8 * buffer2,
size_t buffer2_len,
struct dmx_section_filter * source,
enum dmx_success success);
typedef int (*dmx_ts_fullness) (
struct dmx_ts_feed *source,
int required_space,
int wait);
typedef int (*dmx_section_fullness) (
struct dmx_section_filter *source,
int required_space,
int wait);
/*--------------------------------------------------------------------------*/
/* DVB Front-End */
/*--------------------------------------------------------------------------*/
enum dmx_frontend_source {
DMX_MEMORY_FE,
DMX_FRONTEND_0,
DMX_FRONTEND_1,
DMX_FRONTEND_2,
DMX_FRONTEND_3,
DMX_STREAM_0, /* external stream input, e.g. LVDS */
DMX_STREAM_1,
DMX_STREAM_2,
DMX_STREAM_3
};
struct dmx_frontend {
struct list_head connectivity_list; /* List of front-ends that can
be connected to a particular
demux */
enum dmx_frontend_source source;
};
/*--------------------------------------------------------------------------*/
/* MPEG-2 TS Demux */
/*--------------------------------------------------------------------------*/
/*
* Flags OR'ed in the capabilities field of struct dmx_demux.
*/
#define DMX_TS_FILTERING 1
#define DMX_PES_FILTERING 2
#define DMX_SECTION_FILTERING 4
#define DMX_MEMORY_BASED_FILTERING 8 /* write() available */
#define DMX_CRC_CHECKING 16
#define DMX_TS_DESCRAMBLING 32
/*
* Demux resource type identifier.
*/
/*
* DMX_FE_ENTRY(): Casts elements in the list of registered
* front-ends from the generic type struct list_head
* to the type * struct dmx_frontend
*.
*/
#define DMX_FE_ENTRY(list) list_entry(list, struct dmx_frontend, connectivity_list)
struct dmx_demux {
u32 capabilities; /* Bitfield of capability flags */
struct dmx_frontend* frontend; /* Front-end connected to the demux */
void* priv; /* Pointer to private data of the API client */
struct data_buffer dvr_input; /* DVR input buffer */
int dvr_input_protected;
struct dentry *debugfs_demux_dir; /* debugfs dir */
int (*open) (struct dmx_demux* demux);
int (*close) (struct dmx_demux* demux);
int (*write) (struct dmx_demux *demux, const char *buf, size_t count);
int (*allocate_ts_feed) (struct dmx_demux* demux,
struct dmx_ts_feed** feed,
dmx_ts_cb callback);
int (*release_ts_feed) (struct dmx_demux* demux,
struct dmx_ts_feed* feed);
int (*allocate_section_feed) (struct dmx_demux* demux,
struct dmx_section_feed** feed,
dmx_section_cb callback);
int (*release_section_feed) (struct dmx_demux* demux,
struct dmx_section_feed* feed);
int (*add_frontend) (struct dmx_demux* demux,
struct dmx_frontend* frontend);
int (*remove_frontend) (struct dmx_demux* demux,
struct dmx_frontend* frontend);
struct list_head* (*get_frontends) (struct dmx_demux* demux);
int (*connect_frontend) (struct dmx_demux* demux,
struct dmx_frontend* frontend);
int (*disconnect_frontend) (struct dmx_demux* demux);
int (*get_pes_pids) (struct dmx_demux* demux, u16 *pids);
int (*get_caps) (struct dmx_demux* demux, struct dmx_caps *caps);
int (*set_source) (struct dmx_demux *demux, const dmx_source_t *src);
int (*set_tsp_format) (struct dmx_demux *demux,
enum dmx_tsp_format_t tsp_format);
int (*set_playback_mode) (struct dmx_demux *demux,
enum dmx_playback_mode_t mode,
dmx_ts_fullness ts_fullness_callback,
dmx_section_fullness sec_fullness_callback);
int (*write_cancel) (struct dmx_demux *demux);
int (*get_stc) (struct dmx_demux* demux, unsigned int num,
u64 *stc, unsigned int *base);
int (*map_buffer) (struct dmx_demux *demux,
struct dmx_buffer *dmx_buffer,
void **priv_handle, void **mem);
int (*unmap_buffer) (struct dmx_demux *demux,
void *priv_handle);
int (*get_tsp_size) (struct dmx_demux *demux);
};
#endif /* #ifndef __DEMUX_H */
|