0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #define pr_fmt(fmt) KBUILD_MODNAME ":%s, %d: " fmt, __func__, __LINE__
0011
0012 #include <linux/math64.h>
0013 #include <linux/printk.h>
0014 #include <linux/ratelimit.h>
0015 #include <linux/types.h>
0016
0017 #include "vidtv_common.h"
0018 #include "vidtv_ts.h"
0019
0020 static u32 vidtv_ts_write_pcr_bits(u8 *to, u32 to_offset, u64 pcr)
0021 {
0022
0023 u64 div;
0024 u64 rem;
0025 u8 *buf = to + to_offset;
0026 u64 pcr_low;
0027 u64 pcr_high;
0028
0029 div = div64_u64_rem(pcr, 300, &rem);
0030
0031 pcr_low = rem;
0032 pcr_high = div;
0033
0034 *buf++ = pcr_high >> 25;
0035 *buf++ = pcr_high >> 17;
0036 *buf++ = pcr_high >> 9;
0037 *buf++ = pcr_high >> 1;
0038 *buf++ = pcr_high << 7 | pcr_low >> 8 | 0x7e;
0039 *buf++ = pcr_low;
0040
0041 return 6;
0042 }
0043
0044 void vidtv_ts_inc_cc(u8 *continuity_counter)
0045 {
0046 ++*continuity_counter;
0047 if (*continuity_counter > TS_CC_MAX_VAL)
0048 *continuity_counter = 0;
0049 }
0050
0051 u32 vidtv_ts_null_write_into(struct null_packet_write_args args)
0052 {
0053 u32 nbytes = 0;
0054 struct vidtv_mpeg_ts ts_header = {};
0055
0056 ts_header.sync_byte = TS_SYNC_BYTE;
0057 ts_header.bitfield = cpu_to_be16(TS_NULL_PACKET_PID);
0058 ts_header.payload = 1;
0059 ts_header.continuity_counter = *args.continuity_counter;
0060
0061
0062 nbytes += vidtv_memcpy(args.dest_buf,
0063 args.dest_offset + nbytes,
0064 args.buf_sz,
0065 &ts_header,
0066 sizeof(ts_header));
0067
0068 vidtv_ts_inc_cc(args.continuity_counter);
0069
0070
0071 nbytes += vidtv_memset(args.dest_buf,
0072 args.dest_offset + nbytes,
0073 args.buf_sz,
0074 TS_FILL_BYTE,
0075 TS_PACKET_LEN - nbytes);
0076
0077
0078 if (nbytes != TS_PACKET_LEN)
0079 pr_warn_ratelimited("Expected exactly %d bytes, got %d\n",
0080 TS_PACKET_LEN,
0081 nbytes);
0082
0083 return nbytes;
0084 }
0085
0086 u32 vidtv_ts_pcr_write_into(struct pcr_write_args args)
0087 {
0088 u32 nbytes = 0;
0089 struct vidtv_mpeg_ts ts_header = {};
0090 struct vidtv_mpeg_ts_adaption ts_adap = {};
0091
0092 ts_header.sync_byte = TS_SYNC_BYTE;
0093 ts_header.bitfield = cpu_to_be16(args.pid);
0094 ts_header.scrambling = 0;
0095
0096 ts_header.continuity_counter = *args.continuity_counter;
0097 ts_header.payload = 0;
0098 ts_header.adaptation_field = 1;
0099
0100
0101 ts_adap.length = 183;
0102 ts_adap.PCR = 1;
0103
0104
0105 nbytes += vidtv_memcpy(args.dest_buf,
0106 args.dest_offset + nbytes,
0107 args.buf_sz,
0108 &ts_header,
0109 sizeof(ts_header));
0110
0111
0112 nbytes += vidtv_memcpy(args.dest_buf,
0113 args.dest_offset + nbytes,
0114 args.buf_sz,
0115 &ts_adap,
0116 sizeof(ts_adap));
0117
0118
0119 nbytes += vidtv_ts_write_pcr_bits(args.dest_buf,
0120 args.dest_offset + nbytes,
0121 args.pcr);
0122
0123 nbytes += vidtv_memset(args.dest_buf,
0124 args.dest_offset + nbytes,
0125 args.buf_sz,
0126 TS_FILL_BYTE,
0127 TS_PACKET_LEN - nbytes);
0128
0129
0130 if (nbytes != TS_PACKET_LEN)
0131 pr_warn_ratelimited("Expected exactly %d bytes, got %d\n",
0132 TS_PACKET_LEN,
0133 nbytes);
0134
0135 return nbytes;
0136 }