Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cd35eb97 authored by Gilad Broner's avatar Gilad Broner Committed by Gerrit - the friendly Code Review server
Browse files

Migrate demux driver from kernel 3.10 to 3.18



This change migrates all the relevant files and updates made
to the dvb/demux framework, required for mpq demux driver.
The snapshot is taken as of msm-3.10, commit 1d1c751febc370 ("Merge "msm:
kgsl: Set IOMMU context and AHB offsets for A5xx"")
In addition, introduce a few code changes to reduce checkpatch warnings,
typos and other style issues.

Change-Id: I5eee6818ff81178470677e981179f029a08a58ef
Signed-off-by: default avatarGilad Broner <gbroner@codeaurora.org>
parent 819f45d3
Loading
Loading
Loading
Loading
+219 −44
Original line number Diff line number Diff line
@@ -7,6 +7,8 @@
 * 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
@@ -36,6 +38,8 @@
/* Common definitions */
/*--------------------------------------------------------------------------*/

#define DMX_EVENT_QUEUE_SIZE	500 /* number of events */

/*
 * DMX_MAX_FILTER_SIZE: Maximum length (in bytes) of a section/PES filter.
 */
@@ -59,15 +63,100 @@
/*
 * 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_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;
};

/*--------------------------------------------------------------------------*/
@@ -83,10 +172,17 @@ enum dmx_success {
#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,
@@ -95,6 +191,34 @@ struct dmx_ts_feed {
		    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);
};

/*--------------------------------------------------------------------------*/
@@ -106,9 +230,15 @@ struct dmx_section_filter {
	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 */
@@ -121,16 +251,26 @@ struct dmx_section_feed {
	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 (*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);
};

/*--------------------------------------------------------------------------*/
@@ -151,6 +291,16 @@ typedef int (*dmx_section_cb) ( const u8 * buffer1,
				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 */
/*--------------------------------------------------------------------------*/
@@ -206,9 +356,15 @@ 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 __user *buf, size_t count);
	int (*write)(struct dmx_demux *demux,
			const char __user *buf,
			size_t count);
	int (*allocate_ts_feed)(struct dmx_demux *demux,
				 struct dmx_ts_feed **feed,
				 dmx_ts_cb callback);
@@ -234,8 +390,27 @@ struct dmx_demux {

	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 */
+3872 −219

File changed.

Preview size limit exceeded, changes collapsed.

+135 −4
Original line number Diff line number Diff line
@@ -4,6 +4,8 @@
 * Copyright (C) 2000 Ralph Metzler & Marcus Metzler
 *                    for convergence integrated media GmbH
 *
 * 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
@@ -33,7 +35,7 @@
#include <linux/string.h>
#include <linux/mutex.h>
#include <linux/slab.h>

#include <linux/kthread.h>
#include <linux/dvb/dmx.h>

#include "dvbdev.h"
@@ -57,10 +59,87 @@ enum dmxdev_state {

struct dmxdev_feed {
	u16 pid;
	struct dmx_indexing_params idx_params;
	struct dmx_cipher_operations cipher_ops;
	struct dmx_ts_feed *ts;
	struct list_head next;
};

struct dmxdev_sec_feed {
	struct dmx_section_feed *feed;
	struct dmx_cipher_operations cipher_ops;
};

struct dmxdev_events_queue {
	/*
	 * indices used to manage events queue.
	 * read_index advanced when relevant data is read
	 * from the buffer.
	 * notified_index is the index from which next events
	 * are returned.
	 * read_index <= notified_index <= write_index
	 *
	 * If user reads the data without getting the respective
	 * event first, the read/notified indices are updated
	 * automatically to reflect the actual data that exist
	 * in the buffer.
	 */
	u32 read_index;
	u32 write_index;
	u32 notified_index;

	/* Bytes read by user without having respective event in the queue */
	u32 bytes_read_no_event;

	/* internal tracking of PES and recording events */
	u32 current_event_data_size;
	u32 current_event_start_offset;

	/* current setting of the events masking */
	struct dmx_events_mask event_mask;

	/*
	 * indicates if an event used for data-reading from demux
	 * filter is enabled or not. These are events on which
	 * user may wait for before calling read() on the demux filter.
	 */
	int data_read_event_masked;

	/*
	 * holds the current number of pending events in the
	 * events queue that are considered as a wake-up source
	 */
	u32 wakeup_events_counter;

	struct dmx_filter_event queue[DMX_EVENT_QUEUE_SIZE];
};

#define DMX_MIN_INSERTION_REPETITION_TIME	25 /* in msec */
struct ts_insertion_buffer {
	/* work scheduled for insertion of this buffer */
	struct delayed_work dwork;

	struct list_head next;

	/* buffer holding TS packets for insertion */
	char *buffer;

	/* buffer size */
	size_t size;

	/* buffer ID from user */
	u32 identifier;

	/* repetition time for the buffer insertion */
	u32 repetition_time;

	/* the recording filter to which this buffer belongs */
	struct dmxdev_filter *dmxdevfilter;

	/* indication whether insertion should be aborted */
	int abort;
};

struct dmxdev_filter {
	union {
		struct dmx_section_filter *sec;
@@ -69,7 +148,7 @@ struct dmxdev_filter {
	union {
		/* list of TS and PES feeds (struct dmxdev_feed) */
		struct list_head ts;
		struct dmx_section_feed *sec;
		struct dmxdev_sec_feed sec;
	} feed;

	union {
@@ -77,19 +156,37 @@ struct dmxdev_filter {
		struct dmx_pes_filter_params pes;
	} params;

	struct dmxdev_events_queue events;

	enum dmxdev_type type;
	enum dmxdev_state state;
	struct dmxdev *dev;
	struct dvb_ringbuffer buffer;
	void *priv_buff_handle;
	enum dmx_buffer_mode buffer_mode;

	struct mutex mutex;

	/* for recording output */
	enum dmx_tsp_format_t dmx_tsp_format;
	u32 rec_chunk_size;

	/* list of buffers used for insertion (struct ts_insertion_buffer) */
	struct list_head insertion_buffers;

	/* End-of-stream indication has been received */
	int eos_state;

	/* only for sections */
	struct timer_list timer;
	int todo;
	u8 secheader[3];
};

	struct dmx_secure_mode sec_mode;

	/* Decoder buffer(s) related */
	struct dmx_decoder_buffers decoder_buffers;
};

struct dmxdev {
	struct dvb_device *dvbdev;
@@ -100,18 +197,52 @@ struct dmxdev {

	int filternum;
	int capabilities;
#define DMXDEV_CAP_DUPLEX	0x01

	enum dmx_playback_mode_t playback_mode;
	dmx_source_t source;

	unsigned int exit:1;
#define DMXDEV_CAP_DUPLEX 1
	unsigned int dvr_in_exit:1;
	unsigned int dvr_processing_input:1;

	struct dmx_frontend *dvr_orig_fe;

	struct dvb_ringbuffer dvr_buffer;
	void *dvr_priv_buff_handle;
	enum dmx_buffer_mode dvr_buffer_mode;
	struct dmxdev_events_queue dvr_output_events;
	struct dmxdev_filter *dvr_feed;
	int dvr_feeds_count;

	struct dvb_ringbuffer dvr_input_buffer;
	enum dmx_buffer_mode dvr_input_buffer_mode;
	struct task_struct *dvr_input_thread;
	/* DVR commands (data feed / OOB command) queue */
	struct dvb_ringbuffer dvr_cmd_buffer;

#define DVR_BUFFER_SIZE (10*188*1024)

	struct mutex mutex;
	spinlock_t lock;
	spinlock_t dvr_in_lock;
};

enum dvr_cmd {
	DVR_DATA_FEED_CMD,
	DVR_OOB_CMD
};

struct dvr_command {
	enum dvr_cmd type;
	union {
		struct dmx_oob_command oobcmd;
		size_t data_feed_count;
	} cmd;
};

#define DVR_CMDS_BUFFER_SIZE (sizeof(struct dvr_command)*500)


int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *);
void dvb_dmxdev_release(struct dmxdev *dmxdev);
+2427 −322

File changed.

Preview size limit exceeded, changes collapsed.

+274 −0
Original line number Diff line number Diff line
@@ -4,6 +4,8 @@
 * Copyright (C) 2000-2001 Marcus Metzler & Ralph Metzler
 *                         for convergence integrated media GmbH
 *
 * 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
@@ -27,6 +29,7 @@
#include <linux/timer.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <linux/debugfs.h>

#include "demux.h"

@@ -44,6 +47,8 @@

#define MAX_PID 0x1fff

#define TIMESTAMP_LEN	4

#define SPEED_PKTS_INTERVAL 50000

struct dvb_demux_filter {
@@ -64,6 +69,92 @@ struct dvb_demux_filter {

#define DMX_FEED_ENTRY(pos) list_entry(pos, struct dvb_demux_feed, list_head)


struct dmx_index_entry {
	struct dmx_index_event_info event;
	struct list_head next;
};

#define DMX_IDX_EVENT_QUEUE_SIZE	DMX_EVENT_QUEUE_SIZE

struct dvb_demux_rec_info {
	/* Reference counter for number of feeds using this information */
	int ref_count;

	/* Counter for number of TS packets output to recording buffer */
	u64 ts_output_count;

	/* Indexing information */
	struct {
		/*
		 * Minimum TS packet number encountered in recording filter
		 * among all feeds that search for video patterns
		 */
		u64 min_pattern_tsp_num;

		/* Number of indexing-enabled feeds */
		u8 indexing_feeds_num;

		/* Number of feeds with video pattern search request */
		u8 pattern_search_feeds_num;

		/* Index entries pool */
		struct dmx_index_entry events[DMX_IDX_EVENT_QUEUE_SIZE];

		/* List of free entries that can be used for new index events */
		struct list_head free_list;

		/* List holding ready index entries not notified to user yet */
		struct list_head ready_list;
	} idx_info;
};

#define DVB_DMX_MAX_PATTERN_LEN			6
struct dvb_dmx_video_patterns {
	/* the byte pattern to look for */
	u8 pattern[DVB_DMX_MAX_PATTERN_LEN];

	/* the byte mask to use (same length as pattern) */
	u8 mask[DVB_DMX_MAX_PATTERN_LEN];

	/* the length of the pattern, in bytes */
	size_t size;

	/* the type of the pattern. One of DMX_IDX_* definitions */
	u64 type;
};

#define DVB_DMX_MAX_FOUND_PATTERNS					20
#define DVB_DMX_MAX_SEARCH_PATTERN_NUM				20
struct dvb_dmx_video_prefix_size_masks {
	/*
	 * a bit mask (per pattern) of possible prefix sizes to use
	 * when searching for a pattern that started in the previous TS packet.
	 * Updated by dvb_dmx_video_pattern_search for use in the next lookup.
	 */
	u32 size_mask[DVB_DMX_MAX_FOUND_PATTERNS];
};

struct dvb_dmx_video_patterns_results {
	struct {
		/*
		 * The offset in the buffer where the pattern was found.
		 * If a pattern is found using a prefix (i.e. started on the
		 * previous buffer), offset is zero.
		 */
		u32 offset;

		/*
		 * The type of the pattern found.
		 * One of DMX_IDX_* definitions.
		 */
		u64 type;

		/* The prefix size that was used to find this pattern */
		u32 used_prefix_size;
	} info[DVB_DMX_MAX_FOUND_PATTERNS];
};

struct dvb_demux_feed {
	union {
		struct dmx_ts_feed ts;
@@ -75,6 +166,11 @@ struct dvb_demux_feed {
		dmx_section_cb sec;
	} cb;

	union {
		dmx_ts_data_ready_cb ts;
		dmx_section_data_ready_cb sec;
	} data_ready_cb;

	struct dvb_demux *demux;
	void *priv;
	int type;
@@ -82,6 +178,9 @@ struct dvb_demux_feed {
	u16 pid;
	u8 *buffer;
	int buffer_size;
	enum dmx_tsp_format_t tsp_out_format;
	struct dmx_secure_mode secure_mode;
	struct dmx_cipher_operations cipher_ops;

	struct timespec timeout;
	struct dvb_demux_filter *filter;
@@ -90,12 +189,34 @@ struct dvb_demux_feed {
	enum dmx_ts_pes pes_type;

	int cc;
	int first_cc;
	int pusi_seen;		/* prevents feeding of garbage from previous section */

	u8 scrambling_bits;

	struct dvb_demux_rec_info *rec_info;
	u64 prev_tsp_num;
	u64 prev_stc;
	u64 curr_pusi_tsp_num;
	u64 prev_pusi_tsp_num;
	int prev_frame_valid;
	u64 prev_frame_type;
	int first_frame_in_seq;
	int first_frame_in_seq_notified;
	u64 last_pattern_tsp_num;
	int pattern_num;
	const struct dvb_dmx_video_patterns *patterns[DVB_DMX_MAX_SEARCH_PATTERN_NUM];
	struct dvb_dmx_video_prefix_size_masks prefix_size;
	u16 peslen;
	u32 pes_tei_counter;
	u32 pes_cont_err_counter;
	u32 pes_ts_packets_num;

	struct list_head list_head;
	unsigned int index;	/* a unique index for each feed (can be used as hardware pid filter index) */

	enum dmx_video_codec video_codec;
	struct dmx_indexing_params idx_params;
};

struct dvb_demux {
@@ -107,10 +228,27 @@ struct dvb_demux {
	int (*stop_feed)(struct dvb_demux_feed *feed);
	int (*write_to_decoder)(struct dvb_demux_feed *feed,
				 const u8 *buf, size_t len);
	int (*decoder_fullness_init)(struct dvb_demux_feed *feed);
	int (*decoder_fullness_wait)(struct dvb_demux_feed *feed,
				 size_t required_space);
	int (*decoder_fullness_abort)(struct dvb_demux_feed *feed);
	int (*decoder_buffer_status)(struct dvb_demux_feed *feed,
				struct dmx_buffer_status *dmx_buffer_status);
	int (*reuse_decoder_buffer)(struct dvb_demux_feed *feed,
				int cookie);
	int (*set_cipher_op)(struct dvb_demux_feed *feed,
				struct dmx_cipher_operations *cipher_ops);
	u32 (*check_crc32)(struct dvb_demux_feed *feed,
			    const u8 *buf, size_t len);
	void (*memcopy)(struct dvb_demux_feed *feed, u8 *dst,
			 const u8 *src, size_t len);
	int (*oob_command)(struct dvb_demux_feed *feed,
		struct dmx_oob_command *cmd);
	void (*convert_ts)(struct dvb_demux_feed *feed,
			 const u8 timestamp[TIMESTAMP_LEN],
			 u64 *timestampIn27Mhz);
	int (*set_indexing)(struct dvb_demux_feed *feed);
	int (*flush_decoder_buffer)(struct dvb_demux_feed *feed, size_t length);

	int users;
#define MAX_DVB_DEMUX_USERS 10
@@ -136,10 +274,35 @@ struct dvb_demux {

	struct timespec speed_last_time; /* for TS speed check */
	uint32_t speed_pkts_cnt; /* for TS speed check */

	enum dmx_tsp_format_t tsp_format;
	size_t ts_packet_size;

	enum dmx_playback_mode_t playback_mode;
	int sw_filter_abort;

	struct {
		dmx_ts_fullness ts;
		dmx_section_fullness sec;
	} buffer_ctrl;

	struct dvb_demux_rec_info *rec_info_pool;

	/*
	 * the following is used for debugfs exposing info
	 * about dvb demux performance.
	 */
#define MAX_DVB_DEMUX_NAME_LEN 10
	char alias[MAX_DVB_DEMUX_NAME_LEN];

	u32 total_process_time;
	u32 total_crc_time;
};

int dvb_dmx_init(struct dvb_demux *dvbdemux);
void dvb_dmx_release(struct dvb_demux *dvbdemux);
int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, const u8 *buf,
	int should_lock);
void dvb_dmx_swfilter_packets(struct dvb_demux *dvbdmx, const u8 *buf,
			      size_t count);
void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count);
@@ -147,5 +310,116 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf,
			  size_t count);
void dvb_dmx_swfilter_raw(struct dvb_demux *demux, const u8 *buf,
			  size_t count);
void dvb_dmx_swfilter_format(
			struct dvb_demux *demux, const u8 *buf,
			size_t count,
			enum dmx_tsp_format_t tsp_format);
void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf,
				const u8 timestamp[TIMESTAMP_LEN]);
const struct dvb_dmx_video_patterns *dvb_dmx_get_pattern(u64 dmx_idx_pattern);
int dvb_dmx_video_pattern_search(
		const struct dvb_dmx_video_patterns
			*patterns[DVB_DMX_MAX_SEARCH_PATTERN_NUM],
		int patterns_num,
		const u8 *buf, size_t buf_size,
		struct dvb_dmx_video_prefix_size_masks *prefix_size_masks,
		struct dvb_dmx_video_patterns_results *results);
int dvb_demux_push_idx_event(struct dvb_demux_feed *feed,
		struct dmx_index_event_info *idx_event, int should_lock);
void dvb_dmx_process_idx_pattern(struct dvb_demux_feed *feed,
		struct dvb_dmx_video_patterns_results *patterns, int pattern,
		u64 curr_stc, u64 prev_stc,
		u64 curr_match_tsp, u64 prev_match_tsp,
		u64 curr_pusi_tsp, u64 prev_pusi_tsp);
void dvb_dmx_notify_idx_events(struct dvb_demux_feed *feed, int should_lock);
int dvb_dmx_notify_section_event(struct dvb_demux_feed *feed,
	struct dmx_data_ready *event, int should_lock);
void dvbdmx_ts_reset_pes_state(struct dvb_demux_feed *feed);

/**
 * dvb_dmx_is_video_feed - Returns whether the PES feed
 * is video one.
 *
 * @feed: The feed to be checked.
 *
 * Return     1 if feed is video feed, 0 otherwise.
 */
static inline int dvb_dmx_is_video_feed(struct dvb_demux_feed *feed)
{
	if (feed->type != DMX_TYPE_TS)
		return 0;

	if (feed->ts_type & (~TS_DECODER))
		return 0;

	if ((feed->pes_type == DMX_PES_VIDEO0) ||
		(feed->pes_type == DMX_PES_VIDEO1) ||
		(feed->pes_type == DMX_PES_VIDEO2) ||
		(feed->pes_type == DMX_PES_VIDEO3))
		return 1;

	return 0;
}

/**
 * dvb_dmx_is_pcr_feed - Returns whether the PES feed
 * is PCR one.
 *
 * @feed: The feed to be checked.
 *
 * Return     1 if feed is PCR feed, 0 otherwise.
 */
static inline int dvb_dmx_is_pcr_feed(struct dvb_demux_feed *feed)
{
	if (feed->type != DMX_TYPE_TS)
		return 0;

	if (feed->ts_type & (~TS_DECODER))
		return 0;

	if ((feed->pes_type == DMX_PES_PCR0) ||
		(feed->pes_type == DMX_PES_PCR1) ||
		(feed->pes_type == DMX_PES_PCR2) ||
		(feed->pes_type == DMX_PES_PCR3))
		return 1;

	return 0;
}

/**
 * dvb_dmx_is_sec_feed - Returns whether this is a section feed
 *
 * @feed: The feed to be checked.
 *
 * Return 1 if feed is a section feed, 0 otherwise.
 */
static inline int dvb_dmx_is_sec_feed(struct dvb_demux_feed *feed)
{
	return (feed->type == DMX_TYPE_SEC);
}

/**
 * dvb_dmx_is_rec_feed - Returns whether this is a recording feed
 *
 * @feed: The feed to be checked.
 *
 * Return 1 if feed is recording feed, 0 otherwise.
 */
static inline int dvb_dmx_is_rec_feed(struct dvb_demux_feed *feed)
{
	if (feed->type != DMX_TYPE_TS)
		return 0;

	if (feed->ts_type & (TS_DECODER | TS_PAYLOAD_ONLY))
		return 0;

	return 1;
}

static inline u16 ts_pid(const u8 *buf)
{
	return ((buf[1] & 0x1f) << 8) + buf[2];
}


#endif /* _DVB_DEMUX_H_ */
Loading