Daniel W. S. Almeida | f90cf60 | 2020-08-21 14:58:47 +0200 | [diff] [blame] | 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 logic to translate the ES data for one access unit |
| 8 | * from an encoder into MPEG TS packets. It does so by first encapsulating it |
| 9 | * with a PES header and then splitting it into TS packets. |
| 10 | * |
| 11 | * Copyright (C) 2020 Daniel W. S. Almeida |
| 12 | */ |
| 13 | |
| 14 | #ifndef VIDTV_PES_H |
| 15 | #define VIDTV_PES_H |
| 16 | |
Daniel W. S. Almeida | f90cf60 | 2020-08-21 14:58:47 +0200 | [diff] [blame] | 17 | #include <linux/types.h> |
| 18 | |
| 19 | #include "vidtv_common.h" |
| 20 | |
| 21 | #define PES_MAX_LEN 65536 /* Set 'length' to 0 if greater. Only possible for video. */ |
| 22 | #define PES_START_CODE_PREFIX 0x001 /* 00 00 01 */ |
| 23 | |
| 24 | /* Used when sending PTS, but not DTS */ |
| 25 | struct vidtv_pes_optional_pts { |
| 26 | u8 pts1; |
| 27 | __be16 pts2; |
| 28 | __be16 pts3; |
| 29 | } __packed; |
| 30 | |
| 31 | /* Used when sending both PTS and DTS */ |
| 32 | struct vidtv_pes_optional_pts_dts { |
| 33 | u8 pts1; |
| 34 | __be16 pts2; |
| 35 | __be16 pts3; |
| 36 | |
| 37 | u8 dts1; |
| 38 | __be16 dts2; |
| 39 | __be16 dts3; |
| 40 | } __packed; |
| 41 | |
| 42 | /* PES optional flags */ |
| 43 | struct vidtv_pes_optional { |
| 44 | /* |
| 45 | * These flags show which components are actually |
Mauro Carvalho Chehab | d6a36ed | 2020-09-20 10:14:28 +0200 | [diff] [blame] | 46 | * present in the "optional fields" in the optional PES |
Daniel W. S. Almeida | f90cf60 | 2020-08-21 14:58:47 +0200 | [diff] [blame] | 47 | * header and which are not |
| 48 | * |
| 49 | * u16 two:2; //0x2 |
| 50 | * u16 PES_scrambling_control:2; |
| 51 | * u16 PES_priority:1; |
| 52 | * u16 data_alignment_indicator:1; // unused |
| 53 | * u16 copyright:1; |
| 54 | * u16 original_or_copy:1; |
| 55 | * u16 PTS_DTS:2; |
| 56 | * u16 ESCR:1; |
| 57 | * u16 ES_rate:1; |
| 58 | * u16 DSM_trick_mode:1; |
| 59 | * u16 additional_copy_info:1; |
| 60 | * u16 PES_CRC:1; |
| 61 | * u16 PES_extension:1; |
| 62 | */ |
| 63 | __be16 bitfield; |
| 64 | u8 length; |
| 65 | } __packed; |
| 66 | |
| 67 | /* The PES header */ |
| 68 | struct vidtv_mpeg_pes { |
| 69 | __be32 bitfield; /* packet_start_code_prefix:24, stream_id: 8 */ |
| 70 | /* after this field until the end of the PES data payload */ |
| 71 | __be16 length; |
| 72 | struct vidtv_pes_optional optional[]; |
| 73 | } __packed; |
| 74 | |
| 75 | /** |
| 76 | * struct pes_header_write_args - Arguments to write a PES header. |
| 77 | * @dest_buf: The buffer to write into. |
| 78 | * @dest_offset: where to start writing in the dest_buffer. |
| 79 | * @dest_buf_sz: The size of the dest_buffer |
| 80 | * @encoder_id: Encoder id (see vidtv_encoder.h) |
| 81 | * @send_pts: Should we send PTS? |
| 82 | * @pts: PTS value to send. |
| 83 | * @send_dts: Should we send DTS? |
| 84 | * @dts: DTS value to send. |
| 85 | * @stream_id: The stream id to use. Ex: Audio streams (0xc0-0xdf), Video |
| 86 | * streams (0xe0-0xef). |
| 87 | * @n_pes_h_s_bytes: Padding bytes. Might be used by an encoder if needed, gets |
| 88 | * discarded by the decoder. |
| 89 | * @access_unit_len: The size of _one_ access unit (with any headers it might need) |
| 90 | */ |
| 91 | struct pes_header_write_args { |
| 92 | void *dest_buf; |
| 93 | u32 dest_offset; |
| 94 | u32 dest_buf_sz; |
| 95 | u32 encoder_id; |
| 96 | |
| 97 | bool send_pts; |
| 98 | u64 pts; |
| 99 | |
| 100 | bool send_dts; |
| 101 | u64 dts; |
| 102 | |
| 103 | u16 stream_id; |
| 104 | /* might be used by an encoder if needed, gets discarded by decoder */ |
| 105 | u32 n_pes_h_s_bytes; |
| 106 | u32 access_unit_len; |
| 107 | }; |
| 108 | |
| 109 | /** |
| 110 | * struct pes_ts_header_write_args - Arguments to write a TS header. |
| 111 | * @dest_buf: The buffer to write into. |
| 112 | * @dest_offset: where to start writing in the dest_buffer. |
| 113 | * @dest_buf_sz: The size of the dest_buffer |
| 114 | * @pid: The PID to use for the TS packets. |
| 115 | * @continuity_counter: Incremented on every new TS packet. |
Mauro Carvalho Chehab | 44f2893 | 2020-11-24 11:27:42 +0100 | [diff] [blame] | 116 | * @wrote_pes_header: Flag to indicate that the PES header was written |
| 117 | * @n_stuffing_bytes: Padding bytes. Might be used by an encoder if needed, gets |
Daniel W. S. Almeida | f90cf60 | 2020-08-21 14:58:47 +0200 | [diff] [blame] | 118 | * discarded by the decoder. |
Mauro Carvalho Chehab | 44f2893 | 2020-11-24 11:27:42 +0100 | [diff] [blame] | 119 | * @pcr: counter driven by a 27Mhz clock. |
Daniel W. S. Almeida | f90cf60 | 2020-08-21 14:58:47 +0200 | [diff] [blame] | 120 | */ |
| 121 | struct pes_ts_header_write_args { |
| 122 | void *dest_buf; |
| 123 | u32 dest_offset; |
| 124 | u32 dest_buf_sz; |
| 125 | u16 pid; |
| 126 | u8 *continuity_counter; |
| 127 | bool wrote_pes_header; |
| 128 | u32 n_stuffing_bytes; |
Mauro Carvalho Chehab | a61d7d1 | 2020-09-21 10:05:30 +0200 | [diff] [blame] | 129 | u64 pcr; |
Daniel W. S. Almeida | f90cf60 | 2020-08-21 14:58:47 +0200 | [diff] [blame] | 130 | }; |
| 131 | |
| 132 | /** |
| 133 | * struct pes_write_args - Arguments for the packetizer. |
| 134 | * @dest_buf: The buffer to write into. |
| 135 | * @from: A pointer to the encoder buffer containing one access unit. |
| 136 | * @access_unit_len: The size of _one_ access unit (with any headers it might need) |
| 137 | * @dest_offset: where to start writing in the dest_buffer. |
| 138 | * @dest_buf_sz: The size of the dest_buffer |
| 139 | * @pid: The PID to use for the TS packets. |
| 140 | * @encoder_id: Encoder id (see vidtv_encoder.h) |
| 141 | * @continuity_counter: Incremented on every new TS packet. |
| 142 | * @stream_id: The stream id to use. Ex: Audio streams (0xc0-0xdf), Video |
| 143 | * streams (0xe0-0xef). |
| 144 | * @send_pts: Should we send PTS? |
| 145 | * @pts: PTS value to send. |
| 146 | * @send_dts: Should we send DTS? |
| 147 | * @dts: DTS value to send. |
| 148 | * @n_pes_h_s_bytes: Padding bytes. Might be used by an encoder if needed, gets |
| 149 | * discarded by the decoder. |
Mauro Carvalho Chehab | 44f2893 | 2020-11-24 11:27:42 +0100 | [diff] [blame] | 150 | * @pcr: counter driven by a 27Mhz clock. |
Daniel W. S. Almeida | f90cf60 | 2020-08-21 14:58:47 +0200 | [diff] [blame] | 151 | */ |
| 152 | struct pes_write_args { |
| 153 | void *dest_buf; |
| 154 | void *from; |
| 155 | u32 access_unit_len; |
| 156 | |
| 157 | u32 dest_offset; |
| 158 | u32 dest_buf_sz; |
| 159 | u16 pid; |
| 160 | |
| 161 | u32 encoder_id; |
| 162 | |
| 163 | u8 *continuity_counter; |
| 164 | |
| 165 | u16 stream_id; |
| 166 | |
| 167 | bool send_pts; |
| 168 | u64 pts; |
| 169 | |
| 170 | bool send_dts; |
| 171 | u64 dts; |
| 172 | |
| 173 | u32 n_pes_h_s_bytes; |
Mauro Carvalho Chehab | a61d7d1 | 2020-09-21 10:05:30 +0200 | [diff] [blame] | 174 | u64 pcr; |
Daniel W. S. Almeida | f90cf60 | 2020-08-21 14:58:47 +0200 | [diff] [blame] | 175 | }; |
| 176 | |
| 177 | /** |
| 178 | * vidtv_pes_write_into - Write a PES packet as MPEG-TS packets into a buffer. |
| 179 | * @args: The args to use when writing |
| 180 | * |
| 181 | * This function translate the ES data for one access unit |
| 182 | * from an encoder into MPEG TS packets. It does so by first encapsulating it |
| 183 | * with a PES header and then splitting it into TS packets. |
| 184 | * |
| 185 | * The data is then written into the buffer pointed to by 'args.buf' |
| 186 | * |
| 187 | * Return: The number of bytes written into the buffer. This is usually NOT |
| 188 | * equal to the size of the access unit, since we need space for PES headers, TS headers |
| 189 | * and padding bytes, if any. |
| 190 | */ |
Mauro Carvalho Chehab | 163d72a | 2020-09-22 11:01:17 +0200 | [diff] [blame] | 191 | u32 vidtv_pes_write_into(struct pes_write_args *args); |
Daniel W. S. Almeida | f90cf60 | 2020-08-21 14:58:47 +0200 | [diff] [blame] | 192 | |
| 193 | #endif // VIDTV_PES_H |