File Index
Files and directories
Sign in
FILE

vidtv_ts.c

File preview with syntax highlighting.

linux-6.19.14/drivers/media/test-drivers/vidtv/vidtv_ts.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * The Virtual DVB test driver serves as a reference DVB driver and helps
  4 * validate the existing APIs in the media subsystem. It can also aid
  5 * developers working on userspace applications.
  6 *
  7 * Copyright (C) 2020 Daniel W. S. Almeida
  8 */
  9
 10#define pr_fmt(fmt) KBUILD_MODNAME ":%s, %d: " fmt, __func__, __LINE__
 11
 12#include <linux/math64.h>
 13#include <linux/printk.h>
 14#include <linux/ratelimit.h>
 15#include <linux/types.h>
 16
 17#include "vidtv_common.h"
 18#include "vidtv_ts.h"
 19
 20static u32 vidtv_ts_write_pcr_bits(u8 *to, u32 to_offset, u64 pcr)
 21{
 22	/* Exact same from ffmpeg. PCR is a counter driven by a 27Mhz clock */
 23	u64 div;
 24	u64 rem;
 25	u8 *buf = to + to_offset;
 26	u64 pcr_low;
 27	u64 pcr_high;
 28
 29	div = div64_u64_rem(pcr, 300, &rem);
 30
 31	pcr_low = rem; /* pcr_low = pcr % 300 */
 32	pcr_high = div; /* pcr_high = pcr / 300 */
 33
 34	*buf++ = pcr_high >> 25;
 35	*buf++ = pcr_high >> 17;
 36	*buf++ = pcr_high >>  9;
 37	*buf++ = pcr_high >>  1;
 38	*buf++ = pcr_high <<  7 | pcr_low >> 8 | 0x7e;
 39	*buf++ = pcr_low;
 40
 41	return 6;
 42}
 43
 44void vidtv_ts_inc_cc(u8 *continuity_counter)
 45{
 46	++*continuity_counter;
 47	if (*continuity_counter > TS_CC_MAX_VAL)
 48		*continuity_counter = 0;
 49}
 50
 51u32 vidtv_ts_null_write_into(const struct null_packet_write_args *args)
 52{
 53	u32 nbytes = 0;
 54	struct vidtv_mpeg_ts ts_header = {};
 55
 56	ts_header.sync_byte          = TS_SYNC_BYTE;
 57	ts_header.bitfield           = cpu_to_be16(TS_NULL_PACKET_PID);
 58	ts_header.payload            = 1;
 59	ts_header.continuity_counter = *args->continuity_counter;
 60
 61	/* copy TS header */
 62	nbytes += vidtv_memcpy(args->dest_buf,
 63			       args->dest_offset + nbytes,
 64			       args->buf_sz,
 65			       &ts_header,
 66			       sizeof(ts_header));
 67
 68	vidtv_ts_inc_cc(args->continuity_counter);
 69
 70	/* fill the rest with empty data */
 71	nbytes += vidtv_memset(args->dest_buf,
 72			       args->dest_offset + nbytes,
 73			       args->buf_sz,
 74			       TS_FILL_BYTE,
 75			       TS_PACKET_LEN - nbytes);
 76
 77	/* we should have written exactly _one_ 188byte packet */
 78	if (nbytes != TS_PACKET_LEN)
 79		pr_warn_ratelimited("Expected exactly %d bytes, got %d\n",
 80				    TS_PACKET_LEN,
 81				    nbytes);
 82
 83	return nbytes;
 84}
 85
 86u32 vidtv_ts_pcr_write_into(const struct pcr_write_args *args)
 87{
 88	u32 nbytes = 0;
 89	struct vidtv_mpeg_ts ts_header = {};
 90	struct vidtv_mpeg_ts_adaption ts_adap = {};
 91
 92	ts_header.sync_byte     = TS_SYNC_BYTE;
 93	ts_header.bitfield      = cpu_to_be16(args->pid);
 94	ts_header.scrambling    = 0;
 95	/* cc is not incremented, but it is needed. see 13818-1 clause 2.4.3.3 */
 96	ts_header.continuity_counter = *args->continuity_counter;
 97	ts_header.payload            = 0;
 98	ts_header.adaptation_field   = 1;
 99
100	/* 13818-1 clause 2.4.3.5 */
101	ts_adap.length = 183;
102	ts_adap.PCR    = 1;
103
104	/* copy TS header */
105	nbytes += vidtv_memcpy(args->dest_buf,
106			       args->dest_offset + nbytes,
107			       args->buf_sz,
108			       &ts_header,
109			       sizeof(ts_header));
110
111	/* write the adap after the TS header */
112	nbytes += vidtv_memcpy(args->dest_buf,
113			       args->dest_offset + nbytes,
114			       args->buf_sz,
115			       &ts_adap,
116			       sizeof(ts_adap));
117
118	/* write the PCR optional */
119	nbytes += vidtv_ts_write_pcr_bits(args->dest_buf,
120					  args->dest_offset + nbytes,
121					  args->pcr);
122
123	nbytes += vidtv_memset(args->dest_buf,
124			       args->dest_offset + nbytes,
125			       args->buf_sz,
126			       TS_FILL_BYTE,
127			       TS_PACKET_LEN - nbytes);
128
129	/* we should have written exactly _one_ 188byte packet */
130	if (nbytes != TS_PACKET_LEN)
131		pr_warn_ratelimited("Expected exactly %d bytes, got %d\n",
132				    TS_PACKET_LEN,
133				    nbytes);
134
135	return nbytes;
136}
~/ Read-only file preview.