diff options
author | Daniel W. S. Almeida <dwlsalmeida@gmail.com> | 2020-08-21 15:58:47 +0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+huawei@kernel.org> | 2020-09-12 10:43:12 +0300 |
commit | f90cf6079bf67988f8b1ad1ade70fc89d0080905 (patch) | |
tree | 4d1273d99190ed09aaa92576c59b8e16fd3dd094 /drivers/media/test-drivers/vidtv/vidtv_pes.h | |
parent | f5ffc3b6edf122966b31acf7ce65ebdad42d1417 (diff) | |
download | linux-f90cf6079bf67988f8b1ad1ade70fc89d0080905.tar.xz |
media: vidtv: add a bridge driver
Digital TV devices consist of several independent hardware components
which are controlled by different drivers.
Each media device is controlled by a group of cooperating drivers with the
bridge driver as the main driver.
This patch adds a bridge driver for the Virtual Digital TV driver [vidtv].
The bridge driver binds to the other drivers, that is, vidtv_tuner and
vidtv_demod and implements the digital demux logic, providing userspace
with a MPEG Transport Stream.
The MPEG related code is split in the following way:
- vidtv_ts: code to work with MPEG TS packets, such as TS headers,
adaptation fields, PCR packets and NULL packets.
- vidtv_psi: this is the PSI generator.
PSI packets contain general information about a MPEG Transport Stream.
A PSI generator is needed so userspace apps can retrieve information
about the Transport Stream and eventually tune into a (dummy) channel.
Because the generator is implemented in a separate file, it can be
reused elsewhere in the media subsystem.
Currently vidtv supports working with 3 PSI tables:
PAT, PMT and SDT.
- vidtv_pes: implements the PES logic to convert encoder data into
MPEG TS packets. These can then be fed into a TS multiplexer and
eventually into userspace.
- vidtv_s302m: implements a S302M encoder to make it possible to
insert PCM audio data in the generated MPEG Transport Stream.
This shall enable passing an audio signal into userspace so it can be
decoded and played by media software.
- vidtv_channels: Implements a 'channel' abstraction
When vidtv boots, it will create some hardcoded channels:
Their services will be concatenated to populate the SDT.
Their programs will be concatenated to populate the PAT
For each program in the PAT, a PMT section will be created
The PMT section for a channel will be assigned its streams.
Every stream will have its corresponding encoder polled to produce TS
packets
These packets may be interleaved by the mux and then delivered to the
bridge
- vidtv_mux - Implements a MPEG TS mux, loosely based on the ffmpeg
implementation
The multiplexer is responsible for polling encoders,
interleaving packets, padding the resulting stream with NULL packets if
necessary and then delivering the resulting TS packets to the bridge
driver so it can feed the demux.
Signed-off-by: Daniel W. S. Almeida <dwlsalmeida@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Diffstat (limited to 'drivers/media/test-drivers/vidtv/vidtv_pes.h')
-rw-r--r-- | drivers/media/test-drivers/vidtv/vidtv_pes.h | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/drivers/media/test-drivers/vidtv/vidtv_pes.h b/drivers/media/test-drivers/vidtv/vidtv_pes.h new file mode 100644 index 000000000000..36443a6e30d3 --- /dev/null +++ b/drivers/media/test-drivers/vidtv/vidtv_pes.h @@ -0,0 +1,189 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Vidtv serves as a reference DVB driver and helps validate the existing APIs + * in the media subsystem. It can also aid developers working on userspace + * applications. + * + * This file contains the logic to translate the ES data for one access unit + * from an encoder into MPEG TS packets. It does so by first encapsulating it + * with a PES header and then splitting it into TS packets. + * + * Copyright (C) 2020 Daniel W. S. Almeida + */ + +#ifndef VIDTV_PES_H +#define VIDTV_PES_H + +#include <asm/byteorder.h> +#include <linux/types.h> + +#include "vidtv_common.h" + +#define PES_MAX_LEN 65536 /* Set 'length' to 0 if greater. Only possible for video. */ +#define PES_START_CODE_PREFIX 0x001 /* 00 00 01 */ + +/* Used when sending PTS, but not DTS */ +struct vidtv_pes_optional_pts { + u8 pts1; + __be16 pts2; + __be16 pts3; +} __packed; + +/* Used when sending both PTS and DTS */ +struct vidtv_pes_optional_pts_dts { + u8 pts1; + __be16 pts2; + __be16 pts3; + + u8 dts1; + __be16 dts2; + __be16 dts3; +} __packed; + +/* PES optional flags */ +struct vidtv_pes_optional { + /* + * These flags show which components are actually + * present in the "optinal fields" in the optinal PES + * header and which are not + * + * u16 two:2; //0x2 + * u16 PES_scrambling_control:2; + * u16 PES_priority:1; + * u16 data_alignment_indicator:1; // unused + * u16 copyright:1; + * u16 original_or_copy:1; + * u16 PTS_DTS:2; + * u16 ESCR:1; + * u16 ES_rate:1; + * u16 DSM_trick_mode:1; + * u16 additional_copy_info:1; + * u16 PES_CRC:1; + * u16 PES_extension:1; + */ + __be16 bitfield; + u8 length; +} __packed; + +/* The PES header */ +struct vidtv_mpeg_pes { + __be32 bitfield; /* packet_start_code_prefix:24, stream_id: 8 */ + /* after this field until the end of the PES data payload */ + __be16 length; + struct vidtv_pes_optional optional[]; +} __packed; + +/** + * struct pes_header_write_args - Arguments to write a PES header. + * @dest_buf: The buffer to write into. + * @dest_offset: where to start writing in the dest_buffer. + * @dest_buf_sz: The size of the dest_buffer + * @encoder_id: Encoder id (see vidtv_encoder.h) + * @send_pts: Should we send PTS? + * @pts: PTS value to send. + * @send_dts: Should we send DTS? + * @dts: DTS value to send. + * @stream_id: The stream id to use. Ex: Audio streams (0xc0-0xdf), Video + * streams (0xe0-0xef). + * @n_pes_h_s_bytes: Padding bytes. Might be used by an encoder if needed, gets + * discarded by the decoder. + * @access_unit_len: The size of _one_ access unit (with any headers it might need) + */ +struct pes_header_write_args { + void *dest_buf; + u32 dest_offset; + u32 dest_buf_sz; + u32 encoder_id; + + bool send_pts; + u64 pts; + + bool send_dts; + u64 dts; + + u16 stream_id; + /* might be used by an encoder if needed, gets discarded by decoder */ + u32 n_pes_h_s_bytes; + u32 access_unit_len; +}; + +/** + * struct pes_ts_header_write_args - Arguments to write a TS header. + * @dest_buf: The buffer to write into. + * @dest_offset: where to start writing in the dest_buffer. + * @dest_buf_sz: The size of the dest_buffer + * @pid: The PID to use for the TS packets. + * @continuity_counter: Incremented on every new TS packet. + * @n_pes_h_s_bytes: Padding bytes. Might be used by an encoder if needed, gets + * discarded by the decoder. + */ +struct pes_ts_header_write_args { + void *dest_buf; + u32 dest_offset; + u32 dest_buf_sz; + u16 pid; + u8 *continuity_counter; + bool wrote_pes_header; + u32 n_stuffing_bytes; +}; + +/** + * struct pes_write_args - Arguments for the packetizer. + * @dest_buf: The buffer to write into. + * @from: A pointer to the encoder buffer containing one access unit. + * @access_unit_len: The size of _one_ access unit (with any headers it might need) + * @dest_offset: where to start writing in the dest_buffer. + * @dest_buf_sz: The size of the dest_buffer + * @pid: The PID to use for the TS packets. + * @encoder_id: Encoder id (see vidtv_encoder.h) + * @continuity_counter: Incremented on every new TS packet. + * @stream_id: The stream id to use. Ex: Audio streams (0xc0-0xdf), Video + * streams (0xe0-0xef). + * @send_pts: Should we send PTS? + * @pts: PTS value to send. + * @send_dts: Should we send DTS? + * @dts: DTS value to send. + * @n_pes_h_s_bytes: Padding bytes. Might be used by an encoder if needed, gets + * discarded by the decoder. + */ +struct pes_write_args { + void *dest_buf; + void *from; + u32 access_unit_len; + + u32 dest_offset; + u32 dest_buf_sz; + u16 pid; + + u32 encoder_id; + + u8 *continuity_counter; + + u16 stream_id; + + bool send_pts; + u64 pts; + + bool send_dts; + u64 dts; + + u32 n_pes_h_s_bytes; +}; + +/** + * vidtv_pes_write_into - Write a PES packet as MPEG-TS packets into a buffer. + * @args: The args to use when writing + * + * This function translate the ES data for one access unit + * from an encoder into MPEG TS packets. It does so by first encapsulating it + * with a PES header and then splitting it into TS packets. + * + * The data is then written into the buffer pointed to by 'args.buf' + * + * Return: The number of bytes written into the buffer. This is usually NOT + * equal to the size of the access unit, since we need space for PES headers, TS headers + * and padding bytes, if any. + */ +u32 vidtv_pes_write_into(struct pes_write_args args); + +#endif // VIDTV_PES_H |