Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Vidtv serves as a reference DVB driver and helps validate the existing APIs
0004  * in the media subsystem. It can also aid developers working on userspace
0005  * applications.
0006  *
0007  * This file contains the muxer logic for TS packets from different
0008  * elementary streams.
0009  *
0010  * Loosely based on libavcodec/mpegtsenc.c
0011  *
0012  * Copyright (C) 2020 Daniel W. S. Almeida
0013  */
0014 
0015 #ifndef VIDTV_MUX_H
0016 #define VIDTV_MUX_H
0017 
0018 #include <linux/hashtable.h>
0019 #include <linux/types.h>
0020 #include <linux/workqueue.h>
0021 
0022 #include <media/dvb_frontend.h>
0023 
0024 #include "vidtv_psi.h"
0025 
0026 /**
0027  * struct vidtv_mux_timing - Timing related information
0028  *
0029  * This is used to decide when PCR or PSI packets should be sent. This will also
0030  * provide storage for the clock, which is used to compute the value for the PCR.
0031  *
0032  * @start_jiffies: The value of 'jiffies' when we started the mux thread.
0033  * @current_jiffies: The value of 'jiffies' for the current iteration.
0034  * @past_jiffies: The value of 'jiffies' for the past iteration.
0035  * @clk: A 27Mhz clock from which we will drive the PCR. Updated proportionally
0036  * on every iteration.
0037  * @pcr_period_usecs: How often we should send PCR packets.
0038  * @si_period_usecs: How often we should send PSI packets.
0039  */
0040 struct vidtv_mux_timing {
0041     u64 start_jiffies;
0042     u64 current_jiffies;
0043     u64 past_jiffies;
0044 
0045     u64 clk;
0046 
0047     u64 pcr_period_usecs;
0048     u64 si_period_usecs;
0049 };
0050 
0051 /**
0052  * struct vidtv_mux_si - Store the PSI context.
0053  *
0054  * This is used to store the PAT, PMT sections and SDT in use by the muxer.
0055  *
0056  * The muxer acquire these by looking into the hardcoded channels in
0057  * vidtv_channel and then periodically sends the TS packets for them>
0058  *
0059  * @pat: The PAT in use by the muxer.
0060  * @pmt_secs: The PMT sections in use by the muxer. One for each program in the PAT.
0061  * @sdt: The SDT in use by the muxer.
0062  * @nit: The NIT in use by the muxer.
0063  * @eit: the EIT in use by the muxer.
0064  */
0065 struct vidtv_mux_si {
0066     /* the SI tables */
0067     struct vidtv_psi_table_pat *pat;
0068     struct vidtv_psi_table_pmt **pmt_secs; /* the PMT sections */
0069     struct vidtv_psi_table_sdt *sdt;
0070     struct vidtv_psi_table_nit *nit;
0071     struct vidtv_psi_table_eit *eit;
0072 };
0073 
0074 /**
0075  * struct vidtv_mux_pid_ctx - Store the context for a given TS PID.
0076  * @pid: The TS PID.
0077  * @cc: The continuity counter for this PID. It is incremented on every TS
0078  * pack and it will wrap around at 0xf0. If the decoder notices a sudden jump in
0079  * this counter this will trigger a discontinuity state.
0080  * @h: This is embedded in a hash table, mapping pid -> vidtv_mux_pid_ctx
0081  */
0082 struct vidtv_mux_pid_ctx {
0083     u16 pid;
0084     u8 cc; /* continuity counter */
0085     struct hlist_node h;
0086 };
0087 
0088 /**
0089  * struct vidtv_mux - A muxer abstraction loosely based in libavcodec/mpegtsenc.c
0090  * @fe: The frontend structure allocated by the muxer.
0091  * @dev: pointer to struct device.
0092  * @timing: Keeps track of timing related information.
0093  * @mux_rate_kbytes_sec: The bit rate for the TS, in kbytes.
0094  * @pid_ctx: A hash table to keep track of per-PID metadata.
0095  * @on_new_packets_available_cb: A callback to inform of new TS packets ready.
0096  * @mux_buf: A pointer to a buffer for this muxer. TS packets are stored there
0097  * and then passed on to the bridge driver.
0098  * @mux_buf_sz: The size for 'mux_buf'.
0099  * @mux_buf_offset: The current offset into 'mux_buf'.
0100  * @channels: The channels associated with this muxer.
0101  * @si: Keeps track of the PSI context.
0102  * @num_streamed_pcr: Number of PCR packets streamed.
0103  * @num_streamed_si: The number of PSI packets streamed.
0104  * @mpeg_thread: Thread responsible for the muxer loop.
0105  * @streaming: whether 'mpeg_thread' is running.
0106  * @pcr_pid: The TS PID used for the PSI packets. All channels will share the
0107  * same PCR.
0108  * @transport_stream_id: The transport stream ID
0109  * @network_id: The network ID
0110  * @network_name: The network name
0111  * @priv: Private data.
0112  */
0113 struct vidtv_mux {
0114     struct dvb_frontend *fe;
0115     struct device *dev;
0116 
0117     struct vidtv_mux_timing timing;
0118 
0119     u32 mux_rate_kbytes_sec;
0120 
0121     DECLARE_HASHTABLE(pid_ctx, 3);
0122 
0123     void (*on_new_packets_available_cb)(void *priv, u8 *buf, u32 npackets);
0124 
0125     u8 *mux_buf;
0126     u32 mux_buf_sz;
0127     u32 mux_buf_offset;
0128 
0129     struct vidtv_channel  *channels;
0130 
0131     struct vidtv_mux_si si;
0132     u64 num_streamed_pcr;
0133     u64 num_streamed_si;
0134 
0135     struct work_struct mpeg_thread;
0136     bool streaming;
0137 
0138     u16 pcr_pid;
0139     u16 transport_stream_id;
0140     u16 network_id;
0141     char *network_name;
0142     void *priv;
0143 };
0144 
0145 /**
0146  * struct vidtv_mux_init_args - Arguments used to inix the muxer.
0147  * @mux_rate_kbytes_sec: The bit rate for the TS, in kbytes.
0148  * @on_new_packets_available_cb: A callback to inform of new TS packets ready.
0149  * @mux_buf_sz: The size for 'mux_buf'.
0150  * @pcr_period_usecs: How often we should send PCR packets.
0151  * @si_period_usecs: How often we should send PSI packets.
0152  * @pcr_pid: The TS PID used for the PSI packets. All channels will share the
0153  * same PCR.
0154  * @transport_stream_id: The transport stream ID
0155  * @channels: an optional list of channels to use
0156  * @network_id: The network ID
0157  * @network_name: The network name
0158  * @priv: Private data.
0159  */
0160 struct vidtv_mux_init_args {
0161     u32 mux_rate_kbytes_sec;
0162     void (*on_new_packets_available_cb)(void *priv, u8 *buf, u32 npackets);
0163     u32 mux_buf_sz;
0164     u64 pcr_period_usecs;
0165     u64 si_period_usecs;
0166     u16 pcr_pid;
0167     u16 transport_stream_id;
0168     struct vidtv_channel *channels;
0169     u16 network_id;
0170     char *network_name;
0171     void *priv;
0172 };
0173 
0174 struct vidtv_mux *vidtv_mux_init(struct dvb_frontend *fe,
0175                  struct device *dev,
0176                  struct vidtv_mux_init_args *args);
0177 void vidtv_mux_destroy(struct vidtv_mux *m);
0178 
0179 void vidtv_mux_start_thread(struct vidtv_mux *m);
0180 void vidtv_mux_stop_thread(struct vidtv_mux *m);
0181 
0182 #endif //VIDTV_MUX_H