vidtv_mux.c (13588B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Vidtv serves as a reference DVB driver and helps validate the existing APIs 4 * in the media subsystem. It can also aid developers working on userspace 5 * applications. 6 * 7 * This file contains the multiplexer logic for TS packets from different 8 * elementary streams 9 * 10 * Loosely based on libavcodec/mpegtsenc.c 11 * 12 * Copyright (C) 2020 Daniel W. S. Almeida 13 */ 14 15#include <linux/delay.h> 16#include <linux/dev_printk.h> 17#include <linux/jiffies.h> 18#include <linux/kernel.h> 19#include <linux/math64.h> 20#include <linux/ratelimit.h> 21#include <linux/slab.h> 22#include <linux/types.h> 23#include <linux/vmalloc.h> 24 25#include "vidtv_channel.h" 26#include "vidtv_common.h" 27#include "vidtv_encoder.h" 28#include "vidtv_mux.h" 29#include "vidtv_pes.h" 30#include "vidtv_psi.h" 31#include "vidtv_ts.h" 32 33static struct vidtv_mux_pid_ctx 34*vidtv_mux_get_pid_ctx(struct vidtv_mux *m, u16 pid) 35{ 36 struct vidtv_mux_pid_ctx *ctx; 37 38 hash_for_each_possible(m->pid_ctx, ctx, h, pid) 39 if (ctx->pid == pid) 40 return ctx; 41 return NULL; 42} 43 44static struct vidtv_mux_pid_ctx 45*vidtv_mux_create_pid_ctx_once(struct vidtv_mux *m, u16 pid) 46{ 47 struct vidtv_mux_pid_ctx *ctx; 48 49 ctx = vidtv_mux_get_pid_ctx(m, pid); 50 if (ctx) 51 return ctx; 52 53 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 54 if (!ctx) 55 return NULL; 56 57 ctx->pid = pid; 58 ctx->cc = 0; 59 hash_add(m->pid_ctx, &ctx->h, pid); 60 61 return ctx; 62} 63 64static void vidtv_mux_pid_ctx_destroy(struct vidtv_mux *m) 65{ 66 struct vidtv_mux_pid_ctx *ctx; 67 struct hlist_node *tmp; 68 int bkt; 69 70 hash_for_each_safe(m->pid_ctx, bkt, tmp, ctx, h) { 71 hash_del(&ctx->h); 72 kfree(ctx); 73 } 74} 75 76static int vidtv_mux_pid_ctx_init(struct vidtv_mux *m) 77{ 78 struct vidtv_psi_table_pat_program *p = m->si.pat->program; 79 u16 pid; 80 81 hash_init(m->pid_ctx); 82 /* push the pcr pid ctx */ 83 if (!vidtv_mux_create_pid_ctx_once(m, m->pcr_pid)) 84 return -ENOMEM; 85 /* push the NULL packet pid ctx */ 86 if (!vidtv_mux_create_pid_ctx_once(m, TS_NULL_PACKET_PID)) 87 goto free; 88 /* push the PAT pid ctx */ 89 if (!vidtv_mux_create_pid_ctx_once(m, VIDTV_PAT_PID)) 90 goto free; 91 /* push the SDT pid ctx */ 92 if (!vidtv_mux_create_pid_ctx_once(m, VIDTV_SDT_PID)) 93 goto free; 94 /* push the NIT pid ctx */ 95 if (!vidtv_mux_create_pid_ctx_once(m, VIDTV_NIT_PID)) 96 goto free; 97 /* push the EIT pid ctx */ 98 if (!vidtv_mux_create_pid_ctx_once(m, VIDTV_EIT_PID)) 99 goto free; 100 101 /* add a ctx for all PMT sections */ 102 while (p) { 103 pid = vidtv_psi_get_pat_program_pid(p); 104 vidtv_mux_create_pid_ctx_once(m, pid); 105 p = p->next; 106 } 107 108 return 0; 109 110free: 111 vidtv_mux_pid_ctx_destroy(m); 112 return -ENOMEM; 113} 114 115static void vidtv_mux_update_clk(struct vidtv_mux *m) 116{ 117 /* call this at every thread iteration */ 118 u64 elapsed_time; 119 120 m->timing.past_jiffies = m->timing.current_jiffies; 121 m->timing.current_jiffies = get_jiffies_64(); 122 123 elapsed_time = jiffies_to_usecs(m->timing.current_jiffies - 124 m->timing.past_jiffies); 125 126 /* update the 27Mhz clock proportionally to the elapsed time */ 127 m->timing.clk += (CLOCK_UNIT_27MHZ / USEC_PER_SEC) * elapsed_time; 128} 129 130static u32 vidtv_mux_push_si(struct vidtv_mux *m) 131{ 132 struct vidtv_psi_pat_write_args pat_args = { 133 .buf = m->mux_buf, 134 .buf_sz = m->mux_buf_sz, 135 .pat = m->si.pat, 136 }; 137 struct vidtv_psi_pmt_write_args pmt_args = { 138 .buf = m->mux_buf, 139 .buf_sz = m->mux_buf_sz, 140 .pcr_pid = m->pcr_pid, 141 }; 142 struct vidtv_psi_sdt_write_args sdt_args = { 143 .buf = m->mux_buf, 144 .buf_sz = m->mux_buf_sz, 145 .sdt = m->si.sdt, 146 }; 147 struct vidtv_psi_nit_write_args nit_args = { 148 .buf = m->mux_buf, 149 .buf_sz = m->mux_buf_sz, 150 .nit = m->si.nit, 151 152 }; 153 struct vidtv_psi_eit_write_args eit_args = { 154 .buf = m->mux_buf, 155 .buf_sz = m->mux_buf_sz, 156 .eit = m->si.eit, 157 }; 158 u32 initial_offset = m->mux_buf_offset; 159 struct vidtv_mux_pid_ctx *pat_ctx; 160 struct vidtv_mux_pid_ctx *pmt_ctx; 161 struct vidtv_mux_pid_ctx *sdt_ctx; 162 struct vidtv_mux_pid_ctx *nit_ctx; 163 struct vidtv_mux_pid_ctx *eit_ctx; 164 u32 nbytes; 165 u16 pmt_pid; 166 u32 i; 167 168 pat_ctx = vidtv_mux_get_pid_ctx(m, VIDTV_PAT_PID); 169 sdt_ctx = vidtv_mux_get_pid_ctx(m, VIDTV_SDT_PID); 170 nit_ctx = vidtv_mux_get_pid_ctx(m, VIDTV_NIT_PID); 171 eit_ctx = vidtv_mux_get_pid_ctx(m, VIDTV_EIT_PID); 172 173 pat_args.offset = m->mux_buf_offset; 174 pat_args.continuity_counter = &pat_ctx->cc; 175 176 m->mux_buf_offset += vidtv_psi_pat_write_into(&pat_args); 177 178 for (i = 0; i < m->si.pat->num_pmt; ++i) { 179 pmt_pid = vidtv_psi_pmt_get_pid(m->si.pmt_secs[i], 180 m->si.pat); 181 182 if (pmt_pid > TS_LAST_VALID_PID) { 183 dev_warn_ratelimited(m->dev, 184 "PID: %d not found\n", pmt_pid); 185 continue; 186 } 187 188 pmt_ctx = vidtv_mux_get_pid_ctx(m, pmt_pid); 189 190 pmt_args.offset = m->mux_buf_offset; 191 pmt_args.pmt = m->si.pmt_secs[i]; 192 pmt_args.pid = pmt_pid; 193 pmt_args.continuity_counter = &pmt_ctx->cc; 194 195 /* write each section into buffer */ 196 m->mux_buf_offset += vidtv_psi_pmt_write_into(&pmt_args); 197 } 198 199 sdt_args.offset = m->mux_buf_offset; 200 sdt_args.continuity_counter = &sdt_ctx->cc; 201 202 m->mux_buf_offset += vidtv_psi_sdt_write_into(&sdt_args); 203 204 nit_args.offset = m->mux_buf_offset; 205 nit_args.continuity_counter = &nit_ctx->cc; 206 207 m->mux_buf_offset += vidtv_psi_nit_write_into(&nit_args); 208 209 eit_args.offset = m->mux_buf_offset; 210 eit_args.continuity_counter = &eit_ctx->cc; 211 212 m->mux_buf_offset += vidtv_psi_eit_write_into(&eit_args); 213 214 nbytes = m->mux_buf_offset - initial_offset; 215 216 m->num_streamed_si++; 217 218 return nbytes; 219} 220 221static u32 vidtv_mux_push_pcr(struct vidtv_mux *m) 222{ 223 struct pcr_write_args args = {}; 224 struct vidtv_mux_pid_ctx *ctx; 225 u32 nbytes = 0; 226 227 ctx = vidtv_mux_get_pid_ctx(m, m->pcr_pid); 228 args.dest_buf = m->mux_buf; 229 args.pid = m->pcr_pid; 230 args.buf_sz = m->mux_buf_sz; 231 args.continuity_counter = &ctx->cc; 232 233 /* the 27Mhz clock will feed both parts of the PCR bitfield */ 234 args.pcr = m->timing.clk; 235 236 nbytes += vidtv_ts_pcr_write_into(args); 237 m->mux_buf_offset += nbytes; 238 239 m->num_streamed_pcr++; 240 241 return nbytes; 242} 243 244static bool vidtv_mux_should_push_pcr(struct vidtv_mux *m) 245{ 246 u64 next_pcr_at; 247 248 if (m->num_streamed_pcr == 0) 249 return true; 250 251 next_pcr_at = m->timing.start_jiffies + 252 usecs_to_jiffies(m->num_streamed_pcr * 253 m->timing.pcr_period_usecs); 254 255 return time_after64(m->timing.current_jiffies, next_pcr_at); 256} 257 258static bool vidtv_mux_should_push_si(struct vidtv_mux *m) 259{ 260 u64 next_si_at; 261 262 if (m->num_streamed_si == 0) 263 return true; 264 265 next_si_at = m->timing.start_jiffies + 266 usecs_to_jiffies(m->num_streamed_si * 267 m->timing.si_period_usecs); 268 269 return time_after64(m->timing.current_jiffies, next_si_at); 270} 271 272static u32 vidtv_mux_packetize_access_units(struct vidtv_mux *m, 273 struct vidtv_encoder *e) 274{ 275 struct pes_write_args args = { 276 .dest_buf = m->mux_buf, 277 .dest_buf_sz = m->mux_buf_sz, 278 .pid = be16_to_cpu(e->es_pid), 279 .encoder_id = e->id, 280 .stream_id = be16_to_cpu(e->stream_id), 281 .send_pts = true, /* forbidden value '01'... */ 282 .send_dts = false, /* ...for PTS_DTS flags */ 283 }; 284 struct vidtv_access_unit *au = e->access_units; 285 u32 initial_offset = m->mux_buf_offset; 286 struct vidtv_mux_pid_ctx *pid_ctx; 287 u32 nbytes = 0; 288 u8 *buf = NULL; 289 290 /* see SMPTE 302M clause 6.4 */ 291 if (args.encoder_id == S302M) { 292 args.send_dts = false; 293 args.send_pts = true; 294 } 295 296 pid_ctx = vidtv_mux_create_pid_ctx_once(m, be16_to_cpu(e->es_pid)); 297 args.continuity_counter = &pid_ctx->cc; 298 299 while (au) { 300 buf = e->encoder_buf + au->offset; 301 args.from = buf; 302 args.access_unit_len = au->nbytes; 303 args.dest_offset = m->mux_buf_offset; 304 args.pts = au->pts; 305 args.pcr = m->timing.clk; 306 307 m->mux_buf_offset += vidtv_pes_write_into(&args); 308 309 au = au->next; 310 } 311 312 /* 313 * clear the encoder state once the ES data has been written to the mux 314 * buffer 315 */ 316 e->clear(e); 317 318 nbytes = m->mux_buf_offset - initial_offset; 319 return nbytes; 320} 321 322static u32 vidtv_mux_poll_encoders(struct vidtv_mux *m) 323{ 324 struct vidtv_channel *cur_chnl = m->channels; 325 struct vidtv_encoder *e = NULL; 326 u32 nbytes = 0; 327 u32 au_nbytes; 328 329 while (cur_chnl) { 330 e = cur_chnl->encoders; 331 332 while (e) { 333 e->encode(e); 334 /* get the TS packets into the mux buffer */ 335 au_nbytes = vidtv_mux_packetize_access_units(m, e); 336 nbytes += au_nbytes; 337 m->mux_buf_offset += au_nbytes; 338 /* grab next encoder */ 339 e = e->next; 340 } 341 342 /* grab the next channel */ 343 cur_chnl = cur_chnl->next; 344 } 345 346 return nbytes; 347} 348 349static u32 vidtv_mux_pad_with_nulls(struct vidtv_mux *m, u32 npkts) 350{ 351 struct null_packet_write_args args = { 352 .dest_buf = m->mux_buf, 353 .buf_sz = m->mux_buf_sz, 354 .dest_offset = m->mux_buf_offset, 355 }; 356 u32 initial_offset = m->mux_buf_offset; 357 struct vidtv_mux_pid_ctx *ctx; 358 u32 nbytes; 359 u32 i; 360 361 ctx = vidtv_mux_get_pid_ctx(m, TS_NULL_PACKET_PID); 362 363 args.continuity_counter = &ctx->cc; 364 365 for (i = 0; i < npkts; ++i) { 366 m->mux_buf_offset += vidtv_ts_null_write_into(args); 367 args.dest_offset = m->mux_buf_offset; 368 } 369 370 nbytes = m->mux_buf_offset - initial_offset; 371 372 /* sanity check */ 373 if (nbytes != npkts * TS_PACKET_LEN) 374 dev_err_ratelimited(m->dev, "%d != %d\n", 375 nbytes, npkts * TS_PACKET_LEN); 376 377 return nbytes; 378} 379 380static void vidtv_mux_clear(struct vidtv_mux *m) 381{ 382 /* clear the packets currently in the mux */ 383 memset(m->mux_buf, 0, m->mux_buf_sz * sizeof(*m->mux_buf)); 384 /* point to the beginning of the buffer again */ 385 m->mux_buf_offset = 0; 386} 387 388#define ERR_RATE 10000000 389static void vidtv_mux_tick(struct work_struct *work) 390{ 391 struct vidtv_mux *m = container_of(work, 392 struct vidtv_mux, 393 mpeg_thread); 394 struct dtv_frontend_properties *c = &m->fe->dtv_property_cache; 395 u32 tot_bits = 0; 396 u32 nbytes; 397 u32 npkts; 398 399 while (m->streaming) { 400 nbytes = 0; 401 402 vidtv_mux_update_clk(m); 403 404 if (vidtv_mux_should_push_pcr(m)) 405 nbytes += vidtv_mux_push_pcr(m); 406 407 if (vidtv_mux_should_push_si(m)) 408 nbytes += vidtv_mux_push_si(m); 409 410 nbytes += vidtv_mux_poll_encoders(m); 411 nbytes += vidtv_mux_pad_with_nulls(m, 256); 412 413 npkts = nbytes / TS_PACKET_LEN; 414 415 /* if the buffer is not aligned there is a bug somewhere */ 416 if (nbytes % TS_PACKET_LEN) 417 dev_err_ratelimited(m->dev, "Misaligned buffer\n"); 418 419 if (m->on_new_packets_available_cb) 420 m->on_new_packets_available_cb(m->priv, 421 m->mux_buf, 422 npkts); 423 424 vidtv_mux_clear(m); 425 426 /* 427 * Update bytes and packet counts at DVBv5 stats 428 * 429 * For now, both pre and post bit counts are identical, 430 * but post BER count can be lower than pre BER, if the error 431 * correction logic discards packages. 432 */ 433 c->pre_bit_count.stat[0].uvalue = nbytes * 8; 434 c->post_bit_count.stat[0].uvalue = nbytes * 8; 435 c->block_count.stat[0].uvalue += npkts; 436 437 /* 438 * Even without any visible errors for the user, the pre-BER 439 * stats usually have an error range up to 1E-6. So, 440 * add some random error increment count to it. 441 * 442 * Please notice that this is a poor guy's implementation, 443 * as it will produce one corrected bit error every time 444 * ceil(total bytes / ERR_RATE) is incremented, without 445 * any sort of (pseudo-)randomness. 446 */ 447 tot_bits += nbytes * 8; 448 if (tot_bits > ERR_RATE) { 449 c->pre_bit_error.stat[0].uvalue++; 450 tot_bits -= ERR_RATE; 451 } 452 453 usleep_range(VIDTV_SLEEP_USECS, VIDTV_MAX_SLEEP_USECS); 454 } 455} 456 457void vidtv_mux_start_thread(struct vidtv_mux *m) 458{ 459 if (m->streaming) { 460 dev_warn_ratelimited(m->dev, "Already streaming. Skipping.\n"); 461 return; 462 } 463 464 m->streaming = true; 465 m->timing.start_jiffies = get_jiffies_64(); 466 schedule_work(&m->mpeg_thread); 467} 468 469void vidtv_mux_stop_thread(struct vidtv_mux *m) 470{ 471 if (m->streaming) { 472 m->streaming = false; /* thread will quit */ 473 cancel_work_sync(&m->mpeg_thread); 474 } 475} 476 477struct vidtv_mux *vidtv_mux_init(struct dvb_frontend *fe, 478 struct device *dev, 479 struct vidtv_mux_init_args *args) 480{ 481 struct vidtv_mux *m; 482 483 m = kzalloc(sizeof(*m), GFP_KERNEL); 484 if (!m) 485 return NULL; 486 487 m->dev = dev; 488 m->fe = fe; 489 m->timing.pcr_period_usecs = args->pcr_period_usecs; 490 m->timing.si_period_usecs = args->si_period_usecs; 491 492 m->mux_rate_kbytes_sec = args->mux_rate_kbytes_sec; 493 494 m->on_new_packets_available_cb = args->on_new_packets_available_cb; 495 496 m->mux_buf = vzalloc(args->mux_buf_sz); 497 if (!m->mux_buf) 498 goto free_mux; 499 500 m->mux_buf_sz = args->mux_buf_sz; 501 502 m->pcr_pid = args->pcr_pid; 503 m->transport_stream_id = args->transport_stream_id; 504 m->priv = args->priv; 505 m->network_id = args->network_id; 506 m->network_name = kstrdup(args->network_name, GFP_KERNEL); 507 m->timing.current_jiffies = get_jiffies_64(); 508 509 if (args->channels) 510 m->channels = args->channels; 511 else 512 if (vidtv_channels_init(m) < 0) 513 goto free_mux_buf; 514 515 /* will alloc data for pmt_sections after initializing pat */ 516 if (vidtv_channel_si_init(m) < 0) 517 goto free_channels; 518 519 INIT_WORK(&m->mpeg_thread, vidtv_mux_tick); 520 521 if (vidtv_mux_pid_ctx_init(m) < 0) 522 goto free_channel_si; 523 524 return m; 525 526free_channel_si: 527 vidtv_channel_si_destroy(m); 528free_channels: 529 vidtv_channels_destroy(m); 530free_mux_buf: 531 vfree(m->mux_buf); 532free_mux: 533 kfree(m); 534 return NULL; 535} 536 537void vidtv_mux_destroy(struct vidtv_mux *m) 538{ 539 vidtv_mux_stop_thread(m); 540 vidtv_mux_pid_ctx_destroy(m); 541 vidtv_channel_si_destroy(m); 542 vidtv_channels_destroy(m); 543 kfree(m->network_name); 544 vfree(m->mux_buf); 545 kfree(m); 546}