18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Vidtv serves as a reference DVB driver and helps validate the existing APIs 48c2ecf20Sopenharmony_ci * in the media subsystem. It can also aid developers working on userspace 58c2ecf20Sopenharmony_ci * applications. 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * This file contains the logic to translate the ES data for one access unit 88c2ecf20Sopenharmony_ci * from an encoder into MPEG TS packets. It does so by first encapsulating it 98c2ecf20Sopenharmony_ci * with a PES header and then splitting it into TS packets. 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci * Copyright (C) 2020 Daniel W. S. Almeida 128c2ecf20Sopenharmony_ci */ 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#ifndef VIDTV_PES_H 158c2ecf20Sopenharmony_ci#define VIDTV_PES_H 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#include <linux/types.h> 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#include "vidtv_common.h" 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#define PES_MAX_LEN 65536 /* Set 'length' to 0 if greater. Only possible for video. */ 228c2ecf20Sopenharmony_ci#define PES_START_CODE_PREFIX 0x001 /* 00 00 01 */ 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci/* Used when sending PTS, but not DTS */ 258c2ecf20Sopenharmony_cistruct vidtv_pes_optional_pts { 268c2ecf20Sopenharmony_ci u8 pts1; 278c2ecf20Sopenharmony_ci __be16 pts2; 288c2ecf20Sopenharmony_ci __be16 pts3; 298c2ecf20Sopenharmony_ci} __packed; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci/* Used when sending both PTS and DTS */ 328c2ecf20Sopenharmony_cistruct vidtv_pes_optional_pts_dts { 338c2ecf20Sopenharmony_ci u8 pts1; 348c2ecf20Sopenharmony_ci __be16 pts2; 358c2ecf20Sopenharmony_ci __be16 pts3; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci u8 dts1; 388c2ecf20Sopenharmony_ci __be16 dts2; 398c2ecf20Sopenharmony_ci __be16 dts3; 408c2ecf20Sopenharmony_ci} __packed; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci/* PES optional flags */ 438c2ecf20Sopenharmony_cistruct vidtv_pes_optional { 448c2ecf20Sopenharmony_ci /* 458c2ecf20Sopenharmony_ci * These flags show which components are actually 468c2ecf20Sopenharmony_ci * present in the "optional fields" in the optional PES 478c2ecf20Sopenharmony_ci * header and which are not 488c2ecf20Sopenharmony_ci * 498c2ecf20Sopenharmony_ci * u16 two:2; //0x2 508c2ecf20Sopenharmony_ci * u16 PES_scrambling_control:2; 518c2ecf20Sopenharmony_ci * u16 PES_priority:1; 528c2ecf20Sopenharmony_ci * u16 data_alignment_indicator:1; // unused 538c2ecf20Sopenharmony_ci * u16 copyright:1; 548c2ecf20Sopenharmony_ci * u16 original_or_copy:1; 558c2ecf20Sopenharmony_ci * u16 PTS_DTS:2; 568c2ecf20Sopenharmony_ci * u16 ESCR:1; 578c2ecf20Sopenharmony_ci * u16 ES_rate:1; 588c2ecf20Sopenharmony_ci * u16 DSM_trick_mode:1; 598c2ecf20Sopenharmony_ci * u16 additional_copy_info:1; 608c2ecf20Sopenharmony_ci * u16 PES_CRC:1; 618c2ecf20Sopenharmony_ci * u16 PES_extension:1; 628c2ecf20Sopenharmony_ci */ 638c2ecf20Sopenharmony_ci __be16 bitfield; 648c2ecf20Sopenharmony_ci u8 length; 658c2ecf20Sopenharmony_ci} __packed; 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci/* The PES header */ 688c2ecf20Sopenharmony_cistruct vidtv_mpeg_pes { 698c2ecf20Sopenharmony_ci __be32 bitfield; /* packet_start_code_prefix:24, stream_id: 8 */ 708c2ecf20Sopenharmony_ci /* after this field until the end of the PES data payload */ 718c2ecf20Sopenharmony_ci __be16 length; 728c2ecf20Sopenharmony_ci struct vidtv_pes_optional optional[]; 738c2ecf20Sopenharmony_ci} __packed; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci/** 768c2ecf20Sopenharmony_ci * struct pes_header_write_args - Arguments to write a PES header. 778c2ecf20Sopenharmony_ci * @dest_buf: The buffer to write into. 788c2ecf20Sopenharmony_ci * @dest_offset: where to start writing in the dest_buffer. 798c2ecf20Sopenharmony_ci * @dest_buf_sz: The size of the dest_buffer 808c2ecf20Sopenharmony_ci * @encoder_id: Encoder id (see vidtv_encoder.h) 818c2ecf20Sopenharmony_ci * @send_pts: Should we send PTS? 828c2ecf20Sopenharmony_ci * @pts: PTS value to send. 838c2ecf20Sopenharmony_ci * @send_dts: Should we send DTS? 848c2ecf20Sopenharmony_ci * @dts: DTS value to send. 858c2ecf20Sopenharmony_ci * @stream_id: The stream id to use. Ex: Audio streams (0xc0-0xdf), Video 868c2ecf20Sopenharmony_ci * streams (0xe0-0xef). 878c2ecf20Sopenharmony_ci * @n_pes_h_s_bytes: Padding bytes. Might be used by an encoder if needed, gets 888c2ecf20Sopenharmony_ci * discarded by the decoder. 898c2ecf20Sopenharmony_ci * @access_unit_len: The size of _one_ access unit (with any headers it might need) 908c2ecf20Sopenharmony_ci */ 918c2ecf20Sopenharmony_cistruct pes_header_write_args { 928c2ecf20Sopenharmony_ci void *dest_buf; 938c2ecf20Sopenharmony_ci u32 dest_offset; 948c2ecf20Sopenharmony_ci u32 dest_buf_sz; 958c2ecf20Sopenharmony_ci u32 encoder_id; 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci bool send_pts; 988c2ecf20Sopenharmony_ci u64 pts; 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci bool send_dts; 1018c2ecf20Sopenharmony_ci u64 dts; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci u16 stream_id; 1048c2ecf20Sopenharmony_ci /* might be used by an encoder if needed, gets discarded by decoder */ 1058c2ecf20Sopenharmony_ci u32 n_pes_h_s_bytes; 1068c2ecf20Sopenharmony_ci u32 access_unit_len; 1078c2ecf20Sopenharmony_ci}; 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci/** 1108c2ecf20Sopenharmony_ci * struct pes_ts_header_write_args - Arguments to write a TS header. 1118c2ecf20Sopenharmony_ci * @dest_buf: The buffer to write into. 1128c2ecf20Sopenharmony_ci * @dest_offset: where to start writing in the dest_buffer. 1138c2ecf20Sopenharmony_ci * @dest_buf_sz: The size of the dest_buffer 1148c2ecf20Sopenharmony_ci * @pid: The PID to use for the TS packets. 1158c2ecf20Sopenharmony_ci * @continuity_counter: Incremented on every new TS packet. 1168c2ecf20Sopenharmony_ci * @wrote_pes_header: Flag to indicate that the PES header was written 1178c2ecf20Sopenharmony_ci * @n_stuffing_bytes: Padding bytes. Might be used by an encoder if needed, gets 1188c2ecf20Sopenharmony_ci * discarded by the decoder. 1198c2ecf20Sopenharmony_ci * @pcr: counter driven by a 27Mhz clock. 1208c2ecf20Sopenharmony_ci */ 1218c2ecf20Sopenharmony_cistruct pes_ts_header_write_args { 1228c2ecf20Sopenharmony_ci void *dest_buf; 1238c2ecf20Sopenharmony_ci u32 dest_offset; 1248c2ecf20Sopenharmony_ci u32 dest_buf_sz; 1258c2ecf20Sopenharmony_ci u16 pid; 1268c2ecf20Sopenharmony_ci u8 *continuity_counter; 1278c2ecf20Sopenharmony_ci bool wrote_pes_header; 1288c2ecf20Sopenharmony_ci u32 n_stuffing_bytes; 1298c2ecf20Sopenharmony_ci u64 pcr; 1308c2ecf20Sopenharmony_ci}; 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci/** 1338c2ecf20Sopenharmony_ci * struct pes_write_args - Arguments for the packetizer. 1348c2ecf20Sopenharmony_ci * @dest_buf: The buffer to write into. 1358c2ecf20Sopenharmony_ci * @from: A pointer to the encoder buffer containing one access unit. 1368c2ecf20Sopenharmony_ci * @access_unit_len: The size of _one_ access unit (with any headers it might need) 1378c2ecf20Sopenharmony_ci * @dest_offset: where to start writing in the dest_buffer. 1388c2ecf20Sopenharmony_ci * @dest_buf_sz: The size of the dest_buffer 1398c2ecf20Sopenharmony_ci * @pid: The PID to use for the TS packets. 1408c2ecf20Sopenharmony_ci * @encoder_id: Encoder id (see vidtv_encoder.h) 1418c2ecf20Sopenharmony_ci * @continuity_counter: Incremented on every new TS packet. 1428c2ecf20Sopenharmony_ci * @stream_id: The stream id to use. Ex: Audio streams (0xc0-0xdf), Video 1438c2ecf20Sopenharmony_ci * streams (0xe0-0xef). 1448c2ecf20Sopenharmony_ci * @send_pts: Should we send PTS? 1458c2ecf20Sopenharmony_ci * @pts: PTS value to send. 1468c2ecf20Sopenharmony_ci * @send_dts: Should we send DTS? 1478c2ecf20Sopenharmony_ci * @dts: DTS value to send. 1488c2ecf20Sopenharmony_ci * @n_pes_h_s_bytes: Padding bytes. Might be used by an encoder if needed, gets 1498c2ecf20Sopenharmony_ci * discarded by the decoder. 1508c2ecf20Sopenharmony_ci * @pcr: counter driven by a 27Mhz clock. 1518c2ecf20Sopenharmony_ci */ 1528c2ecf20Sopenharmony_cistruct pes_write_args { 1538c2ecf20Sopenharmony_ci void *dest_buf; 1548c2ecf20Sopenharmony_ci void *from; 1558c2ecf20Sopenharmony_ci u32 access_unit_len; 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci u32 dest_offset; 1588c2ecf20Sopenharmony_ci u32 dest_buf_sz; 1598c2ecf20Sopenharmony_ci u16 pid; 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci u32 encoder_id; 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci u8 *continuity_counter; 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci u16 stream_id; 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci bool send_pts; 1688c2ecf20Sopenharmony_ci u64 pts; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci bool send_dts; 1718c2ecf20Sopenharmony_ci u64 dts; 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci u32 n_pes_h_s_bytes; 1748c2ecf20Sopenharmony_ci u64 pcr; 1758c2ecf20Sopenharmony_ci}; 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci/** 1788c2ecf20Sopenharmony_ci * vidtv_pes_write_into - Write a PES packet as MPEG-TS packets into a buffer. 1798c2ecf20Sopenharmony_ci * @args: The args to use when writing 1808c2ecf20Sopenharmony_ci * 1818c2ecf20Sopenharmony_ci * This function translate the ES data for one access unit 1828c2ecf20Sopenharmony_ci * from an encoder into MPEG TS packets. It does so by first encapsulating it 1838c2ecf20Sopenharmony_ci * with a PES header and then splitting it into TS packets. 1848c2ecf20Sopenharmony_ci * 1858c2ecf20Sopenharmony_ci * The data is then written into the buffer pointed to by 'args.buf' 1868c2ecf20Sopenharmony_ci * 1878c2ecf20Sopenharmony_ci * Return: The number of bytes written into the buffer. This is usually NOT 1888c2ecf20Sopenharmony_ci * equal to the size of the access unit, since we need space for PES headers, TS headers 1898c2ecf20Sopenharmony_ci * and padding bytes, if any. 1908c2ecf20Sopenharmony_ci */ 1918c2ecf20Sopenharmony_ciu32 vidtv_pes_write_into(struct pes_write_args *args); 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci#endif // VIDTV_PES_H 194