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 multiplexer 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 #include <linux/delay.h>
0016 #include <linux/dev_printk.h>
0017 #include <linux/jiffies.h>
0018 #include <linux/kernel.h>
0019 #include <linux/math64.h>
0020 #include <linux/ratelimit.h>
0021 #include <linux/slab.h>
0022 #include <linux/types.h>
0023 #include <linux/vmalloc.h>
0024 
0025 #include "vidtv_channel.h"
0026 #include "vidtv_common.h"
0027 #include "vidtv_encoder.h"
0028 #include "vidtv_mux.h"
0029 #include "vidtv_pes.h"
0030 #include "vidtv_psi.h"
0031 #include "vidtv_ts.h"
0032 
0033 static struct vidtv_mux_pid_ctx
0034 *vidtv_mux_get_pid_ctx(struct vidtv_mux *m, u16 pid)
0035 {
0036     struct vidtv_mux_pid_ctx *ctx;
0037 
0038     hash_for_each_possible(m->pid_ctx, ctx, h, pid)
0039         if (ctx->pid == pid)
0040             return ctx;
0041     return NULL;
0042 }
0043 
0044 static struct vidtv_mux_pid_ctx
0045 *vidtv_mux_create_pid_ctx_once(struct vidtv_mux *m, u16 pid)
0046 {
0047     struct vidtv_mux_pid_ctx *ctx;
0048 
0049     ctx = vidtv_mux_get_pid_ctx(m, pid);
0050     if (ctx)
0051         return ctx;
0052 
0053     ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
0054     if (!ctx)
0055         return NULL;
0056 
0057     ctx->pid = pid;
0058     ctx->cc  = 0;
0059     hash_add(m->pid_ctx, &ctx->h, pid);
0060 
0061     return ctx;
0062 }
0063 
0064 static void vidtv_mux_pid_ctx_destroy(struct vidtv_mux *m)
0065 {
0066     struct vidtv_mux_pid_ctx *ctx;
0067     struct hlist_node *tmp;
0068     int bkt;
0069 
0070     hash_for_each_safe(m->pid_ctx, bkt, tmp, ctx, h) {
0071         hash_del(&ctx->h);
0072         kfree(ctx);
0073     }
0074 }
0075 
0076 static int vidtv_mux_pid_ctx_init(struct vidtv_mux *m)
0077 {
0078     struct vidtv_psi_table_pat_program *p = m->si.pat->program;
0079     u16 pid;
0080 
0081     hash_init(m->pid_ctx);
0082     /* push the pcr pid ctx */
0083     if (!vidtv_mux_create_pid_ctx_once(m, m->pcr_pid))
0084         return -ENOMEM;
0085     /* push the NULL packet pid ctx */
0086     if (!vidtv_mux_create_pid_ctx_once(m, TS_NULL_PACKET_PID))
0087         goto free;
0088     /* push the PAT pid ctx */
0089     if (!vidtv_mux_create_pid_ctx_once(m, VIDTV_PAT_PID))
0090         goto free;
0091     /* push the SDT pid ctx */
0092     if (!vidtv_mux_create_pid_ctx_once(m, VIDTV_SDT_PID))
0093         goto free;
0094     /* push the NIT pid ctx */
0095     if (!vidtv_mux_create_pid_ctx_once(m, VIDTV_NIT_PID))
0096         goto free;
0097     /* push the EIT pid ctx */
0098     if (!vidtv_mux_create_pid_ctx_once(m, VIDTV_EIT_PID))
0099         goto free;
0100 
0101     /* add a ctx for all PMT sections */
0102     while (p) {
0103         pid = vidtv_psi_get_pat_program_pid(p);
0104         vidtv_mux_create_pid_ctx_once(m, pid);
0105         p = p->next;
0106     }
0107 
0108     return 0;
0109 
0110 free:
0111     vidtv_mux_pid_ctx_destroy(m);
0112     return -ENOMEM;
0113 }
0114 
0115 static void vidtv_mux_update_clk(struct vidtv_mux *m)
0116 {
0117     /* call this at every thread iteration */
0118     u64 elapsed_time;
0119 
0120     m->timing.past_jiffies = m->timing.current_jiffies;
0121     m->timing.current_jiffies = get_jiffies_64();
0122 
0123     elapsed_time = jiffies_to_usecs(m->timing.current_jiffies -
0124                     m->timing.past_jiffies);
0125 
0126     /* update the 27Mhz clock proportionally to the elapsed time */
0127     m->timing.clk += (CLOCK_UNIT_27MHZ / USEC_PER_SEC) * elapsed_time;
0128 }
0129 
0130 static u32 vidtv_mux_push_si(struct vidtv_mux *m)
0131 {
0132     struct vidtv_psi_pat_write_args pat_args = {
0133         .buf                = m->mux_buf,
0134         .buf_sz             = m->mux_buf_sz,
0135         .pat                = m->si.pat,
0136     };
0137     struct vidtv_psi_pmt_write_args pmt_args = {
0138         .buf                = m->mux_buf,
0139         .buf_sz             = m->mux_buf_sz,
0140         .pcr_pid            = m->pcr_pid,
0141     };
0142     struct vidtv_psi_sdt_write_args sdt_args = {
0143         .buf                = m->mux_buf,
0144         .buf_sz             = m->mux_buf_sz,
0145         .sdt                = m->si.sdt,
0146     };
0147     struct vidtv_psi_nit_write_args nit_args = {
0148         .buf                = m->mux_buf,
0149         .buf_sz             = m->mux_buf_sz,
0150         .nit                = m->si.nit,
0151 
0152     };
0153     struct vidtv_psi_eit_write_args eit_args = {
0154         .buf                = m->mux_buf,
0155         .buf_sz             = m->mux_buf_sz,
0156         .eit                = m->si.eit,
0157     };
0158     u32 initial_offset = m->mux_buf_offset;
0159     struct vidtv_mux_pid_ctx *pat_ctx;
0160     struct vidtv_mux_pid_ctx *pmt_ctx;
0161     struct vidtv_mux_pid_ctx *sdt_ctx;
0162     struct vidtv_mux_pid_ctx *nit_ctx;
0163     struct vidtv_mux_pid_ctx *eit_ctx;
0164     u32 nbytes;
0165     u16 pmt_pid;
0166     u32 i;
0167 
0168     pat_ctx = vidtv_mux_get_pid_ctx(m, VIDTV_PAT_PID);
0169     sdt_ctx = vidtv_mux_get_pid_ctx(m, VIDTV_SDT_PID);
0170     nit_ctx = vidtv_mux_get_pid_ctx(m, VIDTV_NIT_PID);
0171     eit_ctx = vidtv_mux_get_pid_ctx(m, VIDTV_EIT_PID);
0172 
0173     pat_args.offset             = m->mux_buf_offset;
0174     pat_args.continuity_counter = &pat_ctx->cc;
0175 
0176     m->mux_buf_offset += vidtv_psi_pat_write_into(&pat_args);
0177 
0178     for (i = 0; i < m->si.pat->num_pmt; ++i) {
0179         pmt_pid = vidtv_psi_pmt_get_pid(m->si.pmt_secs[i],
0180                         m->si.pat);
0181 
0182         if (pmt_pid > TS_LAST_VALID_PID) {
0183             dev_warn_ratelimited(m->dev,
0184                          "PID: %d not found\n", pmt_pid);
0185             continue;
0186         }
0187 
0188         pmt_ctx = vidtv_mux_get_pid_ctx(m, pmt_pid);
0189 
0190         pmt_args.offset             = m->mux_buf_offset;
0191         pmt_args.pmt                = m->si.pmt_secs[i];
0192         pmt_args.pid                = pmt_pid;
0193         pmt_args.continuity_counter = &pmt_ctx->cc;
0194 
0195         /* write each section into buffer */
0196         m->mux_buf_offset += vidtv_psi_pmt_write_into(&pmt_args);
0197     }
0198 
0199     sdt_args.offset             = m->mux_buf_offset;
0200     sdt_args.continuity_counter = &sdt_ctx->cc;
0201 
0202     m->mux_buf_offset += vidtv_psi_sdt_write_into(&sdt_args);
0203 
0204     nit_args.offset             = m->mux_buf_offset;
0205     nit_args.continuity_counter = &nit_ctx->cc;
0206 
0207     m->mux_buf_offset += vidtv_psi_nit_write_into(&nit_args);
0208 
0209     eit_args.offset             = m->mux_buf_offset;
0210     eit_args.continuity_counter = &eit_ctx->cc;
0211 
0212     m->mux_buf_offset += vidtv_psi_eit_write_into(&eit_args);
0213 
0214     nbytes = m->mux_buf_offset - initial_offset;
0215 
0216     m->num_streamed_si++;
0217 
0218     return nbytes;
0219 }
0220 
0221 static u32 vidtv_mux_push_pcr(struct vidtv_mux *m)
0222 {
0223     struct pcr_write_args args = {};
0224     struct vidtv_mux_pid_ctx *ctx;
0225     u32 nbytes = 0;
0226 
0227     ctx                     = vidtv_mux_get_pid_ctx(m, m->pcr_pid);
0228     args.dest_buf           = m->mux_buf;
0229     args.pid                = m->pcr_pid;
0230     args.buf_sz             = m->mux_buf_sz;
0231     args.continuity_counter = &ctx->cc;
0232 
0233     /* the 27Mhz clock will feed both parts of the PCR bitfield */
0234     args.pcr = m->timing.clk;
0235 
0236     nbytes += vidtv_ts_pcr_write_into(args);
0237     m->mux_buf_offset += nbytes;
0238 
0239     m->num_streamed_pcr++;
0240 
0241     return nbytes;
0242 }
0243 
0244 static bool vidtv_mux_should_push_pcr(struct vidtv_mux *m)
0245 {
0246     u64 next_pcr_at;
0247 
0248     if (m->num_streamed_pcr == 0)
0249         return true;
0250 
0251     next_pcr_at = m->timing.start_jiffies +
0252               usecs_to_jiffies(m->num_streamed_pcr *
0253                        m->timing.pcr_period_usecs);
0254 
0255     return time_after64(m->timing.current_jiffies, next_pcr_at);
0256 }
0257 
0258 static bool vidtv_mux_should_push_si(struct vidtv_mux *m)
0259 {
0260     u64 next_si_at;
0261 
0262     if (m->num_streamed_si == 0)
0263         return true;
0264 
0265     next_si_at = m->timing.start_jiffies +
0266              usecs_to_jiffies(m->num_streamed_si *
0267                       m->timing.si_period_usecs);
0268 
0269     return time_after64(m->timing.current_jiffies, next_si_at);
0270 }
0271 
0272 static u32 vidtv_mux_packetize_access_units(struct vidtv_mux *m,
0273                         struct vidtv_encoder *e)
0274 {
0275     struct pes_write_args args = {
0276         .dest_buf           = m->mux_buf,
0277         .dest_buf_sz        = m->mux_buf_sz,
0278         .pid                = be16_to_cpu(e->es_pid),
0279         .encoder_id         = e->id,
0280         .stream_id          = be16_to_cpu(e->stream_id),
0281         .send_pts           = true,  /* forbidden value '01'... */
0282         .send_dts           = false, /* ...for PTS_DTS flags    */
0283     };
0284     struct vidtv_access_unit *au = e->access_units;
0285     u32 initial_offset = m->mux_buf_offset;
0286     struct vidtv_mux_pid_ctx *pid_ctx;
0287     u32 nbytes = 0;
0288     u8 *buf = NULL;
0289 
0290     /* see SMPTE 302M clause 6.4 */
0291     if (args.encoder_id == S302M) {
0292         args.send_dts = false;
0293         args.send_pts = true;
0294     }
0295 
0296     pid_ctx = vidtv_mux_create_pid_ctx_once(m, be16_to_cpu(e->es_pid));
0297     args.continuity_counter = &pid_ctx->cc;
0298 
0299     while (au) {
0300         buf                  = e->encoder_buf + au->offset;
0301         args.from            = buf;
0302         args.access_unit_len = au->nbytes;
0303         args.dest_offset     = m->mux_buf_offset;
0304         args.pts             = au->pts;
0305         args.pcr         = m->timing.clk;
0306 
0307         m->mux_buf_offset += vidtv_pes_write_into(&args);
0308 
0309         au = au->next;
0310     }
0311 
0312     /*
0313      * clear the encoder state once the ES data has been written to the mux
0314      * buffer
0315      */
0316     e->clear(e);
0317 
0318     nbytes = m->mux_buf_offset - initial_offset;
0319     return nbytes;
0320 }
0321 
0322 static u32 vidtv_mux_poll_encoders(struct vidtv_mux *m)
0323 {
0324     struct vidtv_channel *cur_chnl = m->channels;
0325     struct vidtv_encoder *e = NULL;
0326     u32 nbytes = 0;
0327     u32 au_nbytes;
0328 
0329     while (cur_chnl) {
0330         e = cur_chnl->encoders;
0331 
0332         while (e) {
0333             e->encode(e);
0334             /* get the TS packets into the mux buffer */
0335             au_nbytes = vidtv_mux_packetize_access_units(m, e);
0336             nbytes += au_nbytes;
0337             m->mux_buf_offset += au_nbytes;
0338             /* grab next encoder */
0339             e = e->next;
0340         }
0341 
0342         /* grab the next channel */
0343         cur_chnl = cur_chnl->next;
0344     }
0345 
0346     return nbytes;
0347 }
0348 
0349 static u32 vidtv_mux_pad_with_nulls(struct vidtv_mux *m, u32 npkts)
0350 {
0351     struct null_packet_write_args args = {
0352         .dest_buf           = m->mux_buf,
0353         .buf_sz             = m->mux_buf_sz,
0354         .dest_offset        = m->mux_buf_offset,
0355     };
0356     u32 initial_offset = m->mux_buf_offset;
0357     struct vidtv_mux_pid_ctx *ctx;
0358     u32 nbytes;
0359     u32 i;
0360 
0361     ctx = vidtv_mux_get_pid_ctx(m, TS_NULL_PACKET_PID);
0362 
0363     args.continuity_counter = &ctx->cc;
0364 
0365     for (i = 0; i < npkts; ++i) {
0366         m->mux_buf_offset += vidtv_ts_null_write_into(args);
0367         args.dest_offset  = m->mux_buf_offset;
0368     }
0369 
0370     nbytes = m->mux_buf_offset - initial_offset;
0371 
0372     /* sanity check */
0373     if (nbytes != npkts * TS_PACKET_LEN)
0374         dev_err_ratelimited(m->dev, "%d != %d\n",
0375                     nbytes, npkts * TS_PACKET_LEN);
0376 
0377     return nbytes;
0378 }
0379 
0380 static void vidtv_mux_clear(struct vidtv_mux *m)
0381 {
0382     /* clear the packets currently in the mux */
0383     memset(m->mux_buf, 0, m->mux_buf_sz * sizeof(*m->mux_buf));
0384     /* point to the beginning of the buffer again */
0385     m->mux_buf_offset = 0;
0386 }
0387 
0388 #define ERR_RATE 10000000
0389 static void vidtv_mux_tick(struct work_struct *work)
0390 {
0391     struct vidtv_mux *m = container_of(work,
0392                        struct vidtv_mux,
0393                        mpeg_thread);
0394     struct dtv_frontend_properties *c = &m->fe->dtv_property_cache;
0395     u32 tot_bits = 0;
0396     u32 nbytes;
0397     u32 npkts;
0398 
0399     while (m->streaming) {
0400         nbytes = 0;
0401 
0402         vidtv_mux_update_clk(m);
0403 
0404         if (vidtv_mux_should_push_pcr(m))
0405             nbytes += vidtv_mux_push_pcr(m);
0406 
0407         if (vidtv_mux_should_push_si(m))
0408             nbytes += vidtv_mux_push_si(m);
0409 
0410         nbytes += vidtv_mux_poll_encoders(m);
0411         nbytes += vidtv_mux_pad_with_nulls(m, 256);
0412 
0413         npkts = nbytes / TS_PACKET_LEN;
0414 
0415         /* if the buffer is not aligned there is a bug somewhere */
0416         if (nbytes % TS_PACKET_LEN)
0417             dev_err_ratelimited(m->dev, "Misaligned buffer\n");
0418 
0419         if (m->on_new_packets_available_cb)
0420             m->on_new_packets_available_cb(m->priv,
0421                                m->mux_buf,
0422                                npkts);
0423 
0424         vidtv_mux_clear(m);
0425 
0426         /*
0427          * Update bytes and packet counts at DVBv5 stats
0428          *
0429          * For now, both pre and post bit counts are identical,
0430          * but post BER count can be lower than pre BER, if the error
0431          * correction logic discards packages.
0432          */
0433         c->pre_bit_count.stat[0].uvalue = nbytes * 8;
0434         c->post_bit_count.stat[0].uvalue = nbytes * 8;
0435         c->block_count.stat[0].uvalue += npkts;
0436 
0437         /*
0438          * Even without any visible errors for the user, the pre-BER
0439          * stats usually have an error range up to 1E-6. So,
0440          * add some random error increment count to it.
0441          *
0442          * Please notice that this is a poor guy's implementation,
0443          * as it will produce one corrected bit error every time
0444          * ceil(total bytes / ERR_RATE) is incremented, without
0445          * any sort of (pseudo-)randomness.
0446          */
0447         tot_bits += nbytes * 8;
0448         if (tot_bits > ERR_RATE) {
0449             c->pre_bit_error.stat[0].uvalue++;
0450             tot_bits -= ERR_RATE;
0451         }
0452 
0453         usleep_range(VIDTV_SLEEP_USECS, VIDTV_MAX_SLEEP_USECS);
0454     }
0455 }
0456 
0457 void vidtv_mux_start_thread(struct vidtv_mux *m)
0458 {
0459     if (m->streaming) {
0460         dev_warn_ratelimited(m->dev, "Already streaming. Skipping.\n");
0461         return;
0462     }
0463 
0464     m->streaming = true;
0465     m->timing.start_jiffies = get_jiffies_64();
0466     schedule_work(&m->mpeg_thread);
0467 }
0468 
0469 void vidtv_mux_stop_thread(struct vidtv_mux *m)
0470 {
0471     if (m->streaming) {
0472         m->streaming = false; /* thread will quit */
0473         cancel_work_sync(&m->mpeg_thread);
0474     }
0475 }
0476 
0477 struct vidtv_mux *vidtv_mux_init(struct dvb_frontend *fe,
0478                  struct device *dev,
0479                  struct vidtv_mux_init_args *args)
0480 {
0481     struct vidtv_mux *m;
0482 
0483     m = kzalloc(sizeof(*m), GFP_KERNEL);
0484     if (!m)
0485         return NULL;
0486 
0487     m->dev = dev;
0488     m->fe = fe;
0489     m->timing.pcr_period_usecs = args->pcr_period_usecs;
0490     m->timing.si_period_usecs  = args->si_period_usecs;
0491 
0492     m->mux_rate_kbytes_sec = args->mux_rate_kbytes_sec;
0493 
0494     m->on_new_packets_available_cb = args->on_new_packets_available_cb;
0495 
0496     m->mux_buf = vzalloc(args->mux_buf_sz);
0497     if (!m->mux_buf)
0498         goto free_mux;
0499 
0500     m->mux_buf_sz = args->mux_buf_sz;
0501 
0502     m->pcr_pid = args->pcr_pid;
0503     m->transport_stream_id = args->transport_stream_id;
0504     m->priv = args->priv;
0505     m->network_id = args->network_id;
0506     m->network_name = kstrdup(args->network_name, GFP_KERNEL);
0507     m->timing.current_jiffies = get_jiffies_64();
0508 
0509     if (args->channels)
0510         m->channels = args->channels;
0511     else
0512         if (vidtv_channels_init(m) < 0)
0513             goto free_mux_buf;
0514 
0515     /* will alloc data for pmt_sections after initializing pat */
0516     if (vidtv_channel_si_init(m) < 0)
0517         goto free_channels;
0518 
0519     INIT_WORK(&m->mpeg_thread, vidtv_mux_tick);
0520 
0521     if (vidtv_mux_pid_ctx_init(m) < 0)
0522         goto free_channel_si;
0523 
0524     return m;
0525 
0526 free_channel_si:
0527     vidtv_channel_si_destroy(m);
0528 free_channels:
0529     vidtv_channels_destroy(m);
0530 free_mux_buf:
0531     vfree(m->mux_buf);
0532 free_mux:
0533     kfree(m);
0534     return NULL;
0535 }
0536 
0537 void vidtv_mux_destroy(struct vidtv_mux *m)
0538 {
0539     vidtv_mux_stop_thread(m);
0540     vidtv_mux_pid_ctx_destroy(m);
0541     vidtv_channel_si_destroy(m);
0542     vidtv_channels_destroy(m);
0543     kfree(m->network_name);
0544     vfree(m->mux_buf);
0545     kfree(m);
0546 }