9.2.3. vidtv:虛擬數字電視驅動程式

作者:Daniel W. S. Almeida <dwlsalmeida@gmail.com>,2020 年 6 月。

9.2.3.1. 背景

Vidtv 是一個虛擬 DVB 驅動程式,旨在作為驅動程式編寫者的參考模板。它還驗證了現有的媒體 DVB API,從而幫助使用者空間應用程式編寫者。

目前,它包含:

  • 一個假的調諧器驅動程式,如果所選頻率與特定傳輸系統的有效頻率表相差太遠,則會報告訊號質量差。

  • 一個假的解調器驅動程式,它會不斷輪詢調諧器返回的假訊號質量,模擬一個可以根據 CNR 水平丟失/重新獲取訊號鎖定的裝置。

  • 一個假的橋接驅動程式,該模組負責 modprobing 假的調諧器和解調器模組,並實現解複用邏輯。該模組在初始化時接受引數,這些引數將決定模擬的行為方式。

  • 負責編碼有效 MPEG 傳輸流的程式碼,然後將其傳遞給橋接驅動程式。這個假的流包含一些硬編碼的內容。目前,我們有一個只包含單個 MPEG 基本流的音訊頻道,該流又包含一個 SMPTE 302m 編碼的正弦波。請注意,選擇這個特定的編碼器是因為它是以 MPEG 傳輸流編碼 PCM 音訊資料的最簡單方法。

9.2.3.2. 構建 vidtv

vidtv 是一個測試驅動程式,因此在編譯核心時預設情況下 啟用。

為了啟用 vidtv 的編譯:

  • 啟用 DVB_TEST_DRIVERS,然後

  • 啟用 DVB_VIDTV

編譯為模組時,預期以下 .ko 檔案:

  • dvb_vidtv_tuner.ko

  • dvb_vidtv_demod.ko

  • dvb_vidtv_bridge.ko

9.2.3.3. 執行 vidtv

編譯為模組時,執行:

modprobe vidtv

就是這樣!橋接驅動程式將在其自身初始化過程中初始化調諧器和解調器驅動程式。

預設情況下,它將接受以下頻率:

  • DVB-T/T2/C 為 474 MHz;

  • DVB-S/S2 為 11,362 GHz。

對於衛星系統,該驅動程式模擬一個通用擴充套件 LNBf,頻率位於 Ku 波段,範圍從 10.7 GHz 到 12.75 GHz。

您可以選擇性地為 vidtv 定義一些命令列引數。

9.2.3.4. vidtv 的命令列引數

以下是可以提供給 vidtv 的所有引數的列表:

drop_tslock_prob_on_low_snr

如果訊號質量不好,則丟失 TS 鎖定的機率。這個機率將被假的解調器驅動程式使用,以最終返回狀態 0,當訊號質量不好時。

recover_tslock_prob_on_good_snr

當訊號改善時恢復 TS 鎖定的機率。這個機率將被假的解調器驅動程式使用,以最終返回狀態 0x1f,當/如果訊號質量改善時。

mock_power_up_delay_msec

模擬加電延遲。預設值:0。

mock_tune_delay_msec

模擬調諧延遲。預設值:0。

vidtv_valid_dvb_t_freqs

要模擬的有效 DVB-T 頻率,單位為 Hz。

vidtv_valid_dvb_c_freqs

要模擬的有效 DVB-C 頻率,單位為 Hz。

vidtv_valid_dvb_s_freqs

要在 Ku 波段模擬的有效 DVB-S/S2 頻率,單位為 kHz。

max_frequency_shift_hz

調諧頻道時允許的最大頻率偏移,單位為 HZ。

si_period_msec

傳送 SI 資料包的頻率。預設值:40 毫秒。

pcr_period_msec

傳送 PCR 資料包的頻率。預設值:40 毫秒。

mux_rate_kbytes_sec

嘗試透過插入 TS 空資料包來維持此位元率(如果需要)。預設值:4096。

pcr_pid

所有頻道的 PCR PID。預設值:0x200。

mux_buf_sz_pkts

複用器緩衝區的大小,以 188 位元組的倍數表示。

9.2.3.5. vidtv 內部結構

核心模組的拆分方式如下:

vidtv_tuner.[ch]

實現假的調諧器 DVB 驅動程式。

vidtv_demod.[ch]

實現假的解調器 DVB 驅動程式。

vidtv_bridge.[ch]

實現橋接驅動程式。

MPEG 相關程式碼的拆分方式如下:

vidtv_ts.[ch]

用於處理 MPEG TS 資料包的程式碼,例如 TS 標頭、適配欄位、PCR 資料包和 NULL 資料包。

vidtv_psi.[ch]

這是 PSI 生成器。PSI 資料包包含有關 MPEG 傳輸流的常規資訊。需要 PSI 生成器,以便使用者空間應用程式可以檢索有關傳輸流的資訊,並最終調諧到(虛擬)頻道。

由於生成器是在單獨的檔案中實現的,因此可以在媒體子系統中其他地方重複使用。

目前,vidtv 支援使用 5 個 PSI 表:PAT、PMT、SDT、NIT 和 EIT。

PAT 和 PMT 的規範可以在 ISO 13818-1:系統 中找到,而 SDT、NIT、EIT 的規範可以在 ETSI EN 300 468:DVB 系統中的服務資訊 (SI) 規範 中找到。

嚴格來說不是必須的,但是使用真實的 TS 檔案有助於除錯 PSI 表。Vidtv 目前嘗試複製在此檔案中找到的 PSI 結構:TS1Globo.ts

視覺化流結構的好方法是使用 DVBInspector

vidtv_pes.[ch]

實現 PES 邏輯以將編碼器資料轉換為 MPEG TS 資料包。然後可以將這些資料包饋送到 TS 多路複用器,並最終饋送到使用者空間。

vidtv_encoder.h

vidtv 編碼器的介面。可以透過實現此檔案中的呼叫將新編碼器新增到此驅動程式。

vidtv_s302m.[ch]

實現 S302M 編碼器,以便可以將 PCM 音訊資料插入到生成的 MPEG 傳輸流中。相關的規範可線上獲取,如 SMPTE 302M-2007:電視 - 將 AES3 資料對映到 MPEG-2 傳輸流

生成的 MPEG 基本流在帶有 S302M 註冊描述符的私有流中傳送。

這應使音訊訊號可以傳入使用者空間,以便可以透過媒體軟體對其進行解碼和播放。ffmpeg 中相應的解碼器位於 ‘libavcodec/s302m.c’ 中,並且是實驗性的。

vidtv_channel.[ch]

實現“頻道”抽象。

當 vidtv 啟動時,它將建立一些硬編碼的頻道

  1. 它們的服務將被連線起來以填充 SDT。

  2. 它們的節目將被連線起來以填充 PAT。

  3. 它們的事件將被連線起來以填充 EIT。

  4. 對於 PAT 中的每個節目,將建立一個 PMT 部分

  5. 頻道的 PMT 部分將被分配其流。

  6. 每個流都會迴圈輪詢其對應的編碼器以生成 TS 資料包。這些資料包可以被多路複用器交織,然後傳遞到橋接器。

vidtv_mux.[ch]

實現 MPEG TS 多路複用器,大致基於 “libavcodec/mpegtsenc.c” 中的 ffmpeg 實現

多路複用器執行一個迴圈,該迴圈負責:

  1. 跟蹤自上次迭代以來經過的時間。

  2. 輪詢編碼器以獲取 “elapsed_time” 的資料。

  3. 插入 PSI 和/或 PCR 資料包(如果需要)。

  4. 如果需要,使用 NULL 資料包填充生成的流,以保持選定的位元率。

  5. 將生成的 TS 資料包傳遞到橋接驅動程式,以便橋接驅動程式可以將它們傳遞到解複用器。

9.2.3.6. 使用 v4l-utils 測試 vidtv

使用 v4l-utils 中的工具是測試和檢查 vidtv 輸出的好方法。它託管在此處:v4l-utils 文件

從其網頁:

The v4l-utils are a series of packages for handling media devices.

It is hosted at http://git.linuxtv.org/v4l-utils.git, and packaged
on most distributions.

It provides a series of libraries and utilities to be used to
control several aspect of the media boards.

首先安裝 v4l-utils,然後 modprobing vidtv

modprobe dvb_vidtv_bridge

如果驅動程式正常,它應該載入並且其探測程式碼將執行。這將拉入調諧器和解調器驅動程式。

9.2.3.6.1. 使用 dvb-fe-tool

檢查解調器是否成功載入的第一步是執行:

$ dvb-fe-tool
Device Dummy demod for DVB-T/T2/C/S/S2 (/dev/dvb/adapter0/frontend0) capabilities:
    CAN_FEC_1_2
    CAN_FEC_2_3
    CAN_FEC_3_4
    CAN_FEC_4_5
    CAN_FEC_5_6
    CAN_FEC_6_7
    CAN_FEC_7_8
    CAN_FEC_8_9
    CAN_FEC_AUTO
    CAN_GUARD_INTERVAL_AUTO
    CAN_HIERARCHY_AUTO
    CAN_INVERSION_AUTO
    CAN_QAM_16
    CAN_QAM_32
    CAN_QAM_64
    CAN_QAM_128
    CAN_QAM_256
    CAN_QAM_AUTO
    CAN_QPSK
    CAN_TRANSMISSION_MODE_AUTO
DVB API Version 5.11, Current v5 delivery system: DVBC/ANNEX_A
Supported delivery systems:
    DVBT
    DVBT2
    [DVBC/ANNEX_A]
    DVBS
    DVBS2
Frequency range for the current standard:
From:            51.0 MHz
To:              2.15 GHz
Step:            62.5 kHz
Tolerance:       29.5 MHz
Symbol rate ranges for the current standard:
From:            1.00 MBauds
To:              45.0 MBauds

這應該返回當前在解調器結構中設定的內容,即:

static const struct dvb_frontend_ops vidtv_demod_ops = {
        .delsys = {
                SYS_DVBT,
                SYS_DVBT2,
                SYS_DVBC_ANNEX_A,
                SYS_DVBS,
                SYS_DVBS2,
        },

        .info = {
                .name                   = "Dummy demod for DVB-T/T2/C/S/S2",
                .frequency_min_hz       = 51 * MHz,
                .frequency_max_hz       = 2150 * MHz,
                .frequency_stepsize_hz  = 62500,
                .frequency_tolerance_hz = 29500 * kHz,
                .symbol_rate_min        = 1000000,
                .symbol_rate_max        = 45000000,

                .caps = FE_CAN_FEC_1_2 |
                        FE_CAN_FEC_2_3 |
                        FE_CAN_FEC_3_4 |
                        FE_CAN_FEC_4_5 |
                        FE_CAN_FEC_5_6 |
                        FE_CAN_FEC_6_7 |
                        FE_CAN_FEC_7_8 |
                        FE_CAN_FEC_8_9 |
                        FE_CAN_QAM_16 |
                        FE_CAN_QAM_64 |
                        FE_CAN_QAM_32 |
                        FE_CAN_QAM_128 |
                        FE_CAN_QAM_256 |
                        FE_CAN_QAM_AUTO |
                        FE_CAN_QPSK |
                        FE_CAN_FEC_AUTO |
                        FE_CAN_INVERSION_AUTO |
                        FE_CAN_TRANSMISSION_MODE_AUTO |
                        FE_CAN_GUARD_INTERVAL_AUTO |
                        FE_CAN_HIERARCHY_AUTO,
        }

        ....

有關 dvb-fe-tools 的更多資訊,請在此處檢視其線上文件:dvb-fe-tool 文件

9.2.3.6.2. 使用 dvb-scan

為了調諧到頻道並讀取 PSI 表,我們可以使用 dvb-scan。

為此,應提供一個稱為“掃描檔案”的配置檔案,這是一個示例:

[Channel]
FREQUENCY = 474000000
MODULATION = QAM/AUTO
SYMBOL_RATE = 6940000
INNER_FEC = AUTO
DELIVERY_SYSTEM = DVBC/ANNEX_A

注意:

這些引數取決於您正在測試的影片標準。

注意:

Vidtv 是一個假的驅動程式,不會驗證掃描檔案中的太多資訊。對於 DVB-T/DVB-T2,僅指定 “FREQUENCY” 和 “DELIVERY_SYSTEM” 就足夠了。但是,對於 DVB-S/DVB-C,您還應提供 “SYMBOL_RATE”。

您可以在此處線上瀏覽掃描表:dvb-scan-tables

假設此頻道名為 “channel.conf”,則您可以執行:

$ dvbv5-scan channel.conf
dvbv5-scan ~/vidtv.conf
ERROR    command BANDWIDTH_HZ (5) not found during retrieve
Cannot calc frequency shift. Either bandwidth/symbol-rate is unavailable (yet).
Scanning frequency #1 330000000
    (0x00) Signal= -68.00dBm
Scanning frequency #2 474000000
Lock   (0x1f) Signal= -34.45dBm C/N= 33.74dB UCB= 0
Service Beethoven, provider LinuxTV.org: digital television

有關 dvb-scan 的更多資訊,請在此處檢視其線上文件:dvb-scan 文件

9.2.3.6.3. 使用 dvb-zap

dvbv5-zap 是一個命令列工具,可用於將 MPEG-TS 記錄到磁碟。典型的用法是調諧到頻道並將其置於記錄模式。以下示例(摘自文件)說明了這一點[1]

$ dvbv5-zap -c dvb_channel.conf "beethoven" -o music.ts -P -t 10
using demux 'dvb0.demux0'
reading channels from file 'dvb_channel.conf'
tuning to 474000000 Hz
pass all PID's to TS
dvb_set_pesfilter 8192
dvb_dev_set_bufsize: buffer set to 6160384
Lock   (0x1f) Quality= Good Signal= -34.66dBm C/N= 33.41dB UCB= 0 postBER= 0 preBER= 1.05x10^-3 PER= 0
Lock   (0x1f) Quality= Good Signal= -34.57dBm C/N= 33.46dB UCB= 0 postBER= 0 preBER= 1.05x10^-3 PER= 0
Record to file 'music.ts' started
received 24587768 bytes (2401 Kbytes/sec)
Lock   (0x1f) Quality= Good Signal= -34.42dBm C/N= 33.89dB UCB= 0 postBER= 0 preBER= 2.44x10^-3 PER= 0

可以透過使用識別 MPEG-TS 格式的某些播放器(例如 mplayervlc)播放流的內容來觀看頻道。

透過播放流的內容,可以直觀地檢查 vidtv 的工作方式,例如,使用以下命令播放錄製的 TS 檔案:

$ mplayer music.ts

或者,在終端上執行此命令:

$ dvbv5-zap -c dvb_channel.conf "beethoven" -P -r &

並在第二個終端上,使用以下命令從 DVR 介面播放內容:

$ mplayer /dev/dvb/adapter0/dvr0

有關 dvb-zap 的更多資訊,請在此處檢視其線上文件:dvb-zap 文件。另請參見:zap

9.2.3.7. vidtv 中仍然可以改進的內容

9.2.3.7.1. 新增 debugfs 整合

儘管前端驅動程式透過 .read_status 呼叫提供 DVBv5 統計資訊,但一個不錯的補充是使用 debugfs 向用戶空間提供額外的統計資訊,debugfs 是專門為除錯目的而設計的基於 RAM 的簡單易用的檔案系統。

此邏輯將在單獨的檔案中實現,以免汙染前端驅動程式。這些統計資訊是驅動程式特定的,並且在測試期間可能很有用。

Siano 驅動程式是使用 debugfs 將驅動程式特定統計資訊傳遞到使用者空間的一個示例,它可以作為參考。

為了方便起見,應透過 Kconfig 選項進一步啟用和停用此功能。

9.2.3.7.2. 新增一種測試影片的方法

目前,vidtv 只能編碼 PCM 音訊。如果可以實現 MPEG-2 影片編碼的簡化版本,以便我們也可以測試影片,那就太好了。首先要研究的是 ISO 13818-2:資訊科技 — 運動影像及其關聯音訊資訊的通用編碼 — 第 2 部分:影片,其中涵蓋了 MPEG 傳輸流中壓縮影片的編碼。

這可能會選擇性地使用 Video4Linux2 測試模式生成器 v4l2-tpg,它位於

drivers/media/common/v4l2-tpg/

9.2.3.7.3. 新增白噪聲模擬

vidtv 調諧器已經有程式碼可以識別所選頻率是否與有效頻率表相差太遠。目前,這意味著解調器最終可能會丟失訊號鎖定,因為調諧器會報告訊號質量差。

一個不錯的補充是在訊號質量不好時模擬一些噪聲,方法是:

  • 隨機刪除一些 TS 資料包。如果連續性計數器已更新,但資料包未傳遞到解複用器,則這將觸發連續性錯誤。

  • 相應地更新錯誤統計資訊(例如 BER 等)。

  • 模擬編碼資料中的一些噪聲。

9.2.3.8. vidtv 中使用的函式和結構

struct vidtv_dvb

Vidtv 橋接狀態

定義:

struct vidtv_dvb {
    struct platform_device *pdev;
    struct dvb_frontend *fe[NUM_FE];
    struct dvb_adapter adapter;
    struct dvb_demux demux;
    struct dmxdev dmx_dev;
    struct dmx_frontend dmx_fe[NUM_FE];
    struct i2c_adapter i2c_adapter;
    struct i2c_client *i2c_client_demod[NUM_FE];
    struct i2c_client *i2c_client_tuner[NUM_FE];
    u32 nfeeds;
    struct mutex feed_lock;
    bool streaming;
    struct vidtv_mux *mux;
#ifdef CONFIG_MEDIA_CONTROLLER_DVB;
    struct media_device mdev;
#endif ;
};

成員

pdev

平臺裝置。在探測橋接器時獲得。

fe

前端。在探測解調器模組時獲得。

adapter

表示 DTV 介面卡。請參見 “dvb_register_adapter”。

demux

dvb_dmx_swfilter_packets() 呼叫使用的解複用器。

dmx_dev

表示解複用器裝置。

dmx_fe

與解複用器關聯的前端。

i2c_adapter

與橋接驅動程式關聯的 i2c_adapter。

i2c_client_demod

與解調器模組關聯的 i2c_clients。

i2c_client_tuner

與調諧器模組關聯的 i2c_clients。

nfeeds

活動的饋送數。

feed_lock

保護對啟動/停止流邏輯/資料的訪問。

streaming

我們現在是否正在流式傳輸。

mux

負責將 MPEG TS 資料包傳遞到橋接器的抽象。

mdev

媒體控制器支援的 media_device 結構。

struct vidtv_channel

“頻道”抽象

定義:

struct vidtv_channel {
    char *name;
    u16 transport_stream_id;
    struct vidtv_psi_table_sdt_service *service;
    u16 program_num;
    struct vidtv_psi_table_pat_program *program;
    struct vidtv_psi_table_pmt_stream *streams;
    struct vidtv_encoder *encoders;
    struct vidtv_psi_table_eit_event *events;
    struct vidtv_channel *next;
};

成員

name

頻道名稱

transport_stream_id

用於標識 TS 的數字,隨意選擇。

service

_單個_ 服務。將被連線到 SDT 中。

program_num

PAT、PMT 和 SDT 之間的連結。

program

_單個_ 節目,其中包含一個或多個與之關聯的流。將被連線到 PAT 中。

streams

用於填充 “program” 的 PMT 部分的流迴圈

encoders

編碼器迴圈。每個流都必須有一個編碼器。

events

可選事件資訊。這將饋送到 EIT 中。

next

可以選擇性地連結此頻道。

描述

當 vidtv 啟動時,它將建立一些硬編碼的頻道。它們的服務將被連線起來以填充 SDT。它們的節目將被連線起來以填充 PAT。對於 PAT 中的每個節目,將建立一個 PMT 部分。頻道的 PMT 部分將被分配其流。每個流都會輪詢其對應的編碼器以生成 TS 資料包。這些資料包可以被多路複用器交織,然後傳遞到橋接器

int vidtv_channel_si_init(struct vidtv_mux *m)

從多路複用器中的頻道初始化 PSI 表

引數

struct vidtv_mux *m

包含頻道的複用器。

int vidtv_channels_init(struct vidtv_mux *m)

初始化硬編碼的假 “頻道”。

引數

struct vidtv_mux *m

要將頻道儲存到的複用器。

struct vidtv_demod_cnr_to_qual_s

將 CNR 值對映到給定的調製和 fec_inner 組合

定義:

struct vidtv_demod_cnr_to_qual_s {
    u32 modulation;
    u32 fec;
    u32 cnr_ok;
    u32 cnr_good;
};

成員

modulation

請參閱 enum fe_modulation

fec

請參閱 enum fe_fec_rate

cnr_ok

將訊號視為正常的信噪比閾值。低於此閾值,則可能會失去同步。

cnr_good

將訊號視為強的信噪比閾值。

描述

此結構匹配給定調製和 fec_inner 組合的 “good” 和 “ok” CNR 的值。如果訊號質量不太好,我們可能會模擬一些噪聲。

這些值取自 libdvbv5。

struct vidtv_demod_config

用於初始化解調的配置

定義:

struct vidtv_demod_config {
    u8 drop_tslock_prob_on_low_snr;
    u8 recover_tslock_prob_on_good_snr;
};

成員

drop_tslock_prob_on_low_snr

由於低信噪比而導致失去鎖定的機率

recover_tslock_prob_on_good_snr

當訊號改善時恢復的機率

描述

用於初始化解調器模組的配置,通常由橋接驅動程式填充。對於 vidtv,這由 vidtv_bridge 在探測解調器模組之前填充。

struct vidtv_demod_state

解調器狀態

定義:

struct vidtv_demod_state {
    struct dvb_frontend frontend;
    struct vidtv_demod_config config;
    enum fe_status status;
    u16 tuner_cnr;
};

成員

frontend

解調器分配的前端結構。

config

用於初始化解調的配置。

status

解調狀態。

tuner_cnr

訊號載波的當前信噪比

struct vidtv_encoder

通用編碼器型別。

定義:

struct vidtv_encoder {
    enum vidtv_encoder_id id;
    char *name;
    u8 *encoder_buf;
    u32 encoder_buf_sz;
    u32 encoder_buf_offset;
    u64 sample_count;
    struct vidtv_access_unit *access_units;
    void *src_buf;
    u32 src_buf_sz;
    u32 src_buf_offset;
    bool is_video_encoder;
    void *ctx;
    __be16 stream_id;
    __be16 es_pid;
    void *(*encode)(struct vidtv_encoder *e);
    u32 (*clear)(struct vidtv_encoder *e);
    struct vidtv_encoder *sync;
    u32 sampling_rate_hz;
    void (*last_sample_cb)(u32 sample_no);
    void (*destroy)(struct vidtv_encoder *e);
    struct vidtv_encoder *next;
};

成員

id

這樣我們就可以在需要時強制轉換為具體的實現。

name

通常與流名稱相同。

encoder_buf

訪問單元的編碼器內部緩衝區。

encoder_buf_sz

編碼器緩衝區大小(以位元組為單位)

encoder_buf_offset

我們在編碼器緩衝區中的位元組位置。

sample_count

我們總共編碼了多少個樣本。

access_units

編碼器有效負載單元,用於時鐘參考

src_buf

要編碼的原始資料來源,如果為 null,編碼器可能會設定預設值。

src_buf_sz

src_buf 的大小。

src_buf_offset

我們在源緩衝區中的位置。

is_video_encoder

這是否是影片編碼器(而不是音訊編碼器)

ctx

特定於編碼器的狀態。

stream_id

示例:音訊流 (0xc0-0xdf),影片流 (0xe0-0xef)。

es_pid

要在此編碼器的基本流中使用的 TS PID。

encode

為給定的時間量準備足夠的 AU。

clear

清除編碼器輸出。

sync

嘗試與此編碼器同步。

sampling_rate_hz

使用的取樣率(或幀速率,如果是影片)。

last_sample_cb

當編碼器用完資料時呼叫。這是為了讓源以零散的方式讀取資料,而不必一次提供所有資料。

destroy

銷燬此編碼器,釋放已分配的資源。

next

鏈中的下一個

struct vidtv_mux_timing

與計時相關的資訊

定義:

struct vidtv_mux_timing {
    u64 start_jiffies;
    u64 current_jiffies;
    u64 past_jiffies;
    u64 clk;
    u64 pcr_period_usecs;
    u64 si_period_usecs;
};

成員

start_jiffies

當我們啟動複用器執行緒時 ‘jiffies’ 的值。

current_jiffies

當前迭代的 ‘jiffies’ 值。

past_jiffies

過去迭代的 ‘jiffies’ 值。

clk

我們將從中驅動 PCR 的 27Mhz 時鐘。每次迭代都會按比例更新。

pcr_period_usecs

我們應該傳送 PCR 資料包的頻率。

si_period_usecs

我們應該傳送 PSI 資料包的頻率。

描述

這用於決定何時應傳送 PCR 或 PSI 資料包。這還將為時鐘提供儲存空間,時鐘用於計算 PCR 的值。

struct vidtv_mux_si

儲存 PSI 上下文。

定義:

struct vidtv_mux_si {
    struct vidtv_psi_table_pat *pat;
    struct vidtv_psi_table_pmt **pmt_secs;
    struct vidtv_psi_table_sdt *sdt;
    struct vidtv_psi_table_nit *nit;
    struct vidtv_psi_table_eit *eit;
};

成員

pat

複用器使用的 PAT。

pmt_secs

複用器使用的 PMT 部分。PAT 中的每個節目都有一個。

sdt

複用器使用的 SDT。

nit

複用器使用的 NIT。

eit

複用器使用的 EIT。

描述

這用於儲存複用器使用的 PAT、PMT 部分和 SDT。

複用器透過檢視 vidtv_channel 中的硬編碼頻道來獲取這些資訊,然後定期傳送它們的 TS 資料包>

struct vidtv_mux_pid_ctx

儲存給定 TS PID 的上下文。

定義:

struct vidtv_mux_pid_ctx {
    u16 pid;
    u8 cc;
    struct hlist_node h;
};

成員

pid

TS PID。

cc

此 PID 的連續性計數器。它在每個 TS 資料包上遞增,並在 0xf0 處迴繞。如果解碼器注意到此計數器的突然跳躍,則會觸發不連續狀態。

h

這嵌入在雜湊表中,對映 pid -> vidtv_mux_pid_ctx

struct vidtv_mux

一個大致基於 libavcodec/mpegtsenc.c 的多路複用器抽象

定義:

struct vidtv_mux {
    struct dvb_frontend *fe;
    struct device *dev;
    struct vidtv_mux_timing timing;
    u32 mux_rate_kbytes_sec;
    unsigned long pid_ctx[1 << ((3) - 1)];
    void (*on_new_packets_available_cb)(void *priv, u8 *buf, u32 npackets);
    u8 *mux_buf;
    u32 mux_buf_sz;
    u32 mux_buf_offset;
    struct vidtv_channel  *channels;
    struct vidtv_mux_si si;
    u64 num_streamed_pcr;
    u64 num_streamed_si;
    struct work_struct mpeg_thread;
    bool streaming;
    u16 pcr_pid;
    u16 transport_stream_id;
    u16 network_id;
    char *network_name;
    void *priv;
};

成員

fe

複用器分配的前端結構。

dev

指向 struct device 的指標。

timing

跟蹤與計時相關的資訊。

mux_rate_kbytes_sec

TS 的位元率,以 kbytes 為單位。

pid_ctx

用於跟蹤每個 PID 元資料的雜湊表。

on_new_packets_available_cb

一個回撥,用於通知已準備好的新 TS 資料包。

mux_buf

此複用器的緩衝區指標。TS 資料包儲存在此處,然後傳遞到橋接驅動程式。

mux_buf_sz

“mux_buf” 的大小。

mux_buf_offset

“mux_buf” 的當前偏移量。

channels

與此複用器關聯的頻道。

si

跟蹤 PSI 上下文。

num_streamed_pcr

流式傳輸的 PCR 資料包數。

num_streamed_si

流式傳輸的 PSI 資料包數。

mpeg_thread

負責複用器迴圈的執行緒。

streaming

“mpeg_thread” 是否正在執行。

pcr_pid

用於 PSI 資料包的 TS PID。所有頻道將共享同一 PCR。

transport_stream_id

傳輸流 ID

network_id

網路 ID

network_name

網路名稱

priv

私有資料。

struct vidtv_mux_init_args

用於初始化複用器的引數。

定義:

struct vidtv_mux_init_args {
    u32 mux_rate_kbytes_sec;
    void (*on_new_packets_available_cb)(void *priv, u8 *buf, u32 npackets);
    u32 mux_buf_sz;
    u64 pcr_period_usecs;
    u64 si_period_usecs;
    u16 pcr_pid;
    u16 transport_stream_id;
    struct vidtv_channel *channels;
    u16 network_id;
    char *network_name;
    void *priv;
};

成員

mux_rate_kbytes_sec

TS 的位元率,以 kbytes 為單位。

on_new_packets_available_cb

一個回撥,用於通知已準備好的新 TS 資料包。

mux_buf_sz

“mux_buf” 的大小。

pcr_period_usecs

我們應該傳送 PCR 資料包的頻率。

si_period_usecs

我們應該傳送 PSI 資料包的頻率。

pcr_pid

用於 PSI 資料包的 TS PID。所有頻道將共享同一 PCR。

transport_stream_id

傳輸流 ID

channels

要使用的可選頻道列表

network_id

網路 ID

network_name

網路名稱

priv

私有資料。

struct pes_header_write_args

用於寫入 PES 標頭的引數。

定義:

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;
    u32 n_pes_h_s_bytes;
    u32 access_unit_len;
};

成員

dest_buf

要寫入的緩衝區。

dest_offset

從哪裡開始在 dest_buffer 中寫入。

dest_buf_sz

dest_buffer 的大小

encoder_id

編碼器 ID(請參閱 vidtv_encoder.h)

send_pts

我們應該傳送 PTS 嗎?

pts

要傳送的 PTS 值。

send_dts

我們應該傳送 DTS 嗎?

dts

要傳送的 DTS 值。

stream_id

要使用的流 ID。示例:音訊流 (0xc0-0xdf),影片流 (0xe0-0xef)。

n_pes_h_s_bytes

填充位元組。如果需要,編碼器可能會使用,解碼器會丟棄。

access_unit_len

_一個_ 訪問單元的大小(及其可能需要的任何標頭)

struct pes_ts_header_write_args

用於寫入 TS 標頭的引數。

定義:

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;
    u64 pcr;
};

成員

dest_buf

要寫入的緩衝區。

dest_offset

從哪裡開始在 dest_buffer 中寫入。

dest_buf_sz

dest_buffer 的大小

pid

用於 TS 資料包的 PID。

continuity_counter

在每個新 TS 資料包上遞增。

wrote_pes_header

指示 PES 標頭是否已寫入的標誌

n_stuffing_bytes

填充位元組。如果需要,編碼器可能會使用,解碼器會丟棄。

pcr

由 27Mhz 時鐘驅動的計數器。

struct pes_write_args

資料包化器的引數。

定義:

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;
    u64 pcr;
};

成員

dest_buf

要寫入的緩衝區。

from

指向包含一個訪問單元的編碼器緩衝區的指標。

access_unit_len

_一個_ 訪問單元的大小(及其可能需要的任何標頭)

dest_offset

從哪裡開始在 dest_buffer 中寫入。

dest_buf_sz

dest_buffer 的大小

pid

用於 TS 資料包的 PID。

encoder_id

編碼器 ID(請參閱 vidtv_encoder.h)

continuity_counter

在每個新 TS 資料包上遞增。

stream_id

要使用的流 ID。示例:音訊流 (0xc0-0xdf),影片流 (0xe0-0xef)。

send_pts

我們應該傳送 PTS 嗎?

pts

要傳送的 PTS 值。

send_dts

我們應該傳送 DTS 嗎?

dts

要傳送的 DTS 值。

n_pes_h_s_bytes

填充位元組。如果需要,編碼器可能會使用,解碼器會丟棄。

pcr

由 27Mhz 時鐘驅動的計數器。

u32 vidtv_pes_write_into(struct pes_write_args *args)

將 PES 資料包作為 MPEG-TS 資料包寫入緩衝區。

引數

struct pes_write_args *args

寫入時要使用的引數

描述

此函式將來自編碼器的對一個訪問單元的 ES 資料轉換為 MPEG TS 資料包。它首先使用 PES 標頭對其進行封裝,然後將其拆分為 TS 資料包。

然後將資料寫入由 “args.buf” 指向的緩衝區中

返回值

寫入緩衝區的位元組數。 這通常不等於訪問單元的大小,因為我們需要 PES 標頭、TS 標頭和填充位元組(如果有)的空間。

struct psi_write_args

PSI 打包器的引數。

定義:

struct psi_write_args {
    void *dest_buf;
    void *from;
    size_t len;
    u32 dest_offset;
    u16 pid;
    bool new_psi_section;
    u8 *continuity_counter;
    bool is_crc;
    u32 dest_buf_sz;
    u32 *crc;
};

成員

dest_buf

要寫入的緩衝區。

from

要複製的 PSI 資料。

len

要寫入的資料量。

dest_offset

從哪裡開始在 dest_buffer 中寫入。

pid

TS 資料包 ID。

new_psi_section

在啟動表節時設定。

continuity_counter

在每個新資料包上遞增。

is_crc

在末尾寫入 CRC 時設定。

dest_buf_sz

dest_buffer 的大小

crc

用於儲存此塊的 CRC 的指標

struct desc_write_args

用於寫入描述符的引數。

定義:

struct desc_write_args {
    void *dest_buf;
    u32 dest_offset;
    struct vidtv_psi_desc *desc;
    u16 pid;
    u8 *continuity_counter;
    u32 dest_buf_sz;
    u32 *crc;
};

成員

dest_buf

要寫入的緩衝區。

dest_offset

從哪裡開始在 dest_buffer 中寫入。

desc

指向描述符的指標

pid

TS 資料包 ID。

continuity_counter

在每個新資料包上遞增。

dest_buf_sz

dest_buffer 的大小

crc

用於儲存此塊的 CRC 的指標

struct crc32_write_args

用於在 PSI 表末尾寫入 CRC 的引數。

定義:

struct crc32_write_args {
    void *dest_buf;
    u32 dest_offset;
    __be32 crc;
    u16 pid;
    u8 *continuity_counter;
    u32 dest_buf_sz;
};

成員

dest_buf

要寫入的緩衝區。

dest_offset

從哪裡開始在 dest_buffer 中寫入。

crc

要寫入的 CRC 值

pid

TS 資料包 ID。

continuity_counter

在每個新資料包上遞增。

dest_buf_sz

dest_buffer 的大小

struct header_write_args

用於寫入公共表頭的引數

定義:

struct header_write_args {
    void *dest_buf;
    u32 dest_offset;
    struct vidtv_psi_table_header *h;
    u16 pid;
    u8 *continuity_counter;
    u32 dest_buf_sz;
    u32 *crc;
};

成員

dest_buf

要寫入的緩衝區。

dest_offset

從哪裡開始在 dest_buffer 中寫入。

h

指向標頭的指標。

pid

TS 資料包 ID。

continuity_counter

在每個新資料包上遞增。

dest_buf_sz

dest_buffer 的大小

crc

用於儲存此塊的 CRC 的指標

void vidtv_psi_sdt_service_assign(struct vidtv_psi_table_sdt *sdt, struct vidtv_psi_table_sdt_service *service)

將服務迴圈分配給 SDT。

引數

struct vidtv_psi_table_sdt *sdt

要分配給的 SDT。

struct vidtv_psi_table_sdt_service *service

服務迴圈(一個或多個服務)

描述

這將釋放表中的先前服務迴圈。 這會將服務迴圈的所有權分配給表,即,當呼叫其銷燬函式時,該表將釋放此服務迴圈。

void vidtv_psi_desc_assign(struct vidtv_psi_desc **to, struct vidtv_psi_desc *desc)

在某處分配描述符迴圈

引數

struct vidtv_psi_desc **to

將此描述符迴圈分配到何處

struct vidtv_psi_desc *desc

將要分配的描述符迴圈。

描述

這將釋放 “to” 中的迴圈(如果有)。

void vidtv_pmt_desc_assign(struct vidtv_psi_table_pmt *pmt, struct vidtv_psi_desc **to, struct vidtv_psi_desc *desc)

在 PMT 節的某處分配描述符迴圈。

引數

struct vidtv_psi_table_pmt *pmt

將包含描述符迴圈的 PMT 節

struct vidtv_psi_desc **to

在 PMT 中的何處分配此描述符迴圈

struct vidtv_psi_desc *desc

將要分配的描述符迴圈。

描述

這將釋放 “to” 中的迴圈(如果有)。 這會將迴圈的所有權分配給表,即,當呼叫其銷燬函式時,該表將釋放此迴圈。

void vidtv_sdt_desc_assign(struct vidtv_psi_table_sdt *sdt, struct vidtv_psi_desc **to, struct vidtv_psi_desc *desc)

在 SDT 中的某處分配描述符迴圈。

引數

struct vidtv_psi_table_sdt *sdt

將包含描述符迴圈的 SDT

struct vidtv_psi_desc **to

在 PMT 中的何處分配此描述符迴圈

struct vidtv_psi_desc *desc

將要分配的描述符迴圈。

描述

這將釋放 “to” 中的迴圈(如果有)。 這會將迴圈的所有權分配給表,即,當呼叫其銷燬函式時,該表將釋放此迴圈。

void vidtv_psi_pat_program_assign(struct vidtv_psi_table_pat *pat, struct vidtv_psi_table_pat_program *p)

將節目迴圈分配給 PAT。

引數

struct vidtv_psi_table_pat *pat

要分配給的 PAT。

struct vidtv_psi_table_pat_program *p

節目迴圈(一個或多個節目)

描述

這將釋放表中的先前節目迴圈。 這會將節目迴圈的所有權分配給表,即,當呼叫其銷燬函式時,該表將釋放此節目迴圈。

void vidtv_psi_pmt_stream_assign(struct vidtv_psi_table_pmt *pmt, struct vidtv_psi_table_pmt_stream *s)

將流迴圈分配給 PAT。

引數

struct vidtv_psi_table_pmt *pmt

要分配給的 PMT。

struct vidtv_psi_table_pmt_stream *s

流迴圈(一個或多個流)

描述

這將釋放表中的先前流迴圈。 這會將流迴圈的所有權分配給表,即,當呼叫其銷燬函式時,該表將釋放此流迴圈。

struct vidtv_psi_table_pmt **vidtv_psi_pmt_create_sec_for_each_pat_entry(struct vidtv_psi_table_pat *pat, u16 pcr_pid)

為 PAT 中找到的每個節目建立一個 PMT 節

引數

struct vidtv_psi_table_pat *pat

要查詢節目的 PAT。

u16 pcr_pid

用於此 PMT 節中描述的節目的 PCR 的資料包 ID

u16 vidtv_psi_pmt_get_pid(struct vidtv_psi_table_pmt *section, struct vidtv_psi_table_pat *pat)

獲取 PMT 節的 TS PID。

引數

struct vidtv_psi_table_pmt *section

我們要檢索其 PID 的 PMT 節。

struct vidtv_psi_table_pat *pat

要查詢的 PAT 表。

返回值

“section” 的 TS PID

void vidtv_psi_pat_table_update_sec_len(struct vidtv_psi_table_pat *pat)

重新計算並更新 PAT 節長度。

引數

struct vidtv_psi_table_pat *pat

要更新長度的 PAT。

描述

這將遍歷表並累積其元件的長度,然後將其用於替換 “section_length” 欄位。

如果 section_length > MAX_SECTION_LEN,則操作失敗。

void vidtv_psi_pmt_table_update_sec_len(struct vidtv_psi_table_pmt *pmt)

重新計算並更新 PMT 節長度。

引數

struct vidtv_psi_table_pmt *pmt

要更新長度的 PMT。

描述

這將遍歷表並累積其元件的長度,然後將其用於替換 “section_length” 欄位。

如果 section_length > MAX_SECTION_LEN,則操作失敗。

void vidtv_psi_sdt_table_update_sec_len(struct vidtv_psi_table_sdt *sdt)

重新計算並更新 SDT 節長度。

引數

struct vidtv_psi_table_sdt *sdt

要更新長度的 SDT。

描述

這將遍歷表並累積其元件的長度,然後將其用於替換 “section_length” 欄位。

如果 section_length > MAX_SECTION_LEN,則操作失敗。

struct vidtv_psi_pat_write_args

用於寫入 PAT 表的引數

定義:

struct vidtv_psi_pat_write_args {
    char *buf;
    u32 offset;
    struct vidtv_psi_table_pat *pat;
    u32 buf_sz;
    u8 *continuity_counter;
};

成員

buf

目標緩衝區。

offset

目標緩衝區的偏移量。

pat

指向 PAT 的指標。

buf_sz

目標緩衝區的大小。

continuity_counter

指向 CC 的指標。 在每個新資料包上遞增。

u32 vidtv_psi_pat_write_into(struct vidtv_psi_pat_write_args *args)

將 PAT 作為 MPEG-TS 資料包寫入緩衝區。

引數

struct vidtv_psi_pat_write_args *args

struct vidtv_psi_pat_write_args 的一個例項

描述

此函式將 PAT 表的 MPEG TS 資料包寫入緩衝區。 呼叫程式碼通常會透過呼叫其 init 函式來生成 PAT,因此負責釋放它。

返回值

寫入緩衝區的位元組數。 這不等於 PAT 的大小,因為在 TS 封裝期間需要更多空間來容納 TS 標頭。

struct vidtv_psi_sdt_write_args

用於寫入 SDT 表的引數

定義:

struct vidtv_psi_sdt_write_args {
    char *buf;
    u32 offset;
    struct vidtv_psi_table_sdt *sdt;
    u32 buf_sz;
    u8 *continuity_counter;
};

成員

buf

目標緩衝區。

offset

目標緩衝區的偏移量。

sdt

指向 SDT 的指標。

buf_sz

目標緩衝區的大小。

continuity_counter

指向 CC 的指標。 在每個新資料包上遞增。

u32 vidtv_psi_sdt_write_into(struct vidtv_psi_sdt_write_args *args)

將 SDT 作為 MPEG-TS 資料包寫入緩衝區。

引數

struct vidtv_psi_sdt_write_args *args

struct vidtv_psi_sdt_write_args 的一個例項

描述

此函式將 SDT 表的 MPEG TS 資料包寫入緩衝區。 呼叫程式碼通常會透過呼叫其 init 函式來生成 SDT,因此負責釋放它。

返回值

寫入緩衝區的位元組數。 這不等於 SDT 的大小,因為在 TS 封裝期間需要更多空間來容納 TS 標頭。

struct vidtv_psi_pmt_write_args

用於寫入 PMT 節的引數

定義:

struct vidtv_psi_pmt_write_args {
    char *buf;
    u32 offset;
    struct vidtv_psi_table_pmt *pmt;
    u16 pid;
    u32 buf_sz;
    u8 *continuity_counter;
    u16 pcr_pid;
};

成員

buf

目標緩衝區。

offset

目標緩衝區的偏移量。

pmt

指向 PMT 的指標。

pid

節目 ID

buf_sz

目標緩衝區的大小。

continuity_counter

指向 CC 的指標。 在每個新資料包上遞增。

pcr_pid

用於 PSI 資料包的 TS PID。所有頻道將共享同一 PCR。

u32 vidtv_psi_pmt_write_into(struct vidtv_psi_pmt_write_args *args)

將 PMT 作為 MPEG-TS 資料包寫入緩衝區。

引數

struct vidtv_psi_pmt_write_args *args

struct vidtv_psi_pmt_write_args 的一個例項

描述

此函式將 PMT 節的 MPEG TS 資料包寫入緩衝區。 呼叫程式碼通常會透過呼叫其 init 函式來生成 PMT 節,因此負責釋放它。

返回值

寫入緩衝區的位元組數。 這不等於 PMT 節的大小,因為在 TS 封裝期間需要更多空間來容納 TS 標頭。

struct vidtv_psi_table_pmt *vidtv_psi_find_pmt_sec(struct vidtv_psi_table_pmt **pmt_sections, u16 nsections, u16 program_num)

查詢 “program_num” 的 PMT 節

引數

struct vidtv_psi_table_pmt **pmt_sections

要查詢的節。

u16 nsections

節數。

u16 program_num

從指向 PMT 節的 PAT 中的 “program_num”。

返回值

指向 PMT 的指標(如果找到),否則為 NULL。

struct vidtv_psi_table_transport

NIT 和/或其他表的 TS 迴圈中的條目。 請參見 ETSI 300 468 第 5.2.1 節

定義:

struct vidtv_psi_table_transport {
    __be16 transport_id;
    __be16 network_id;
    __be16 bitfield;
    struct vidtv_psi_desc *descriptor;
    struct vidtv_psi_table_transport *next;
};

成員

transport_id

正在描述的 TS ID

network_id

包含 TS ID 的 network_id

bitfield

包含描述符迴圈長度

descriptor

描述符迴圈

next

指向下一個條目的指標

struct vidtv_psi_table_nit

網路資訊表 (NIT)。 請參見 ETSI 300 468 第 5.2.1 節

定義:

struct vidtv_psi_table_nit {
    struct vidtv_psi_table_header header;
    __be16 bitfield;
    struct vidtv_psi_desc *descriptor;
    __be16 bitfield2;
    struct vidtv_psi_table_transport *transport;
};

成員

header

PSI 表頭

bitfield

包含網路描述符長度

descriptor

描述網路的描述符迴圈

bitfield2

包含傳輸流迴圈長度

transport

傳輸流迴圈

struct vidtv_psi_nit_write_args

用於寫入 NIT 節的引數

定義:

struct vidtv_psi_nit_write_args {
    char *buf;
    u32 offset;
    struct vidtv_psi_table_nit *nit;
    u32 buf_sz;
    u8 *continuity_counter;
};

成員

buf

目標緩衝區。

offset

目標緩衝區的偏移量。

nit

指向 NIT 的指標

buf_sz

目標緩衝區的大小。

continuity_counter

指向 CC 的指標。 在每個新資料包上遞增。

u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args *args)

將 NIT 作為 MPEG-TS 資料包寫入緩衝區。

引數

struct vidtv_psi_nit_write_args *args

struct vidtv_psi_nit_write_args 的一個例項

描述

此函式將 NIT 表的 MPEG TS 資料包寫入緩衝區。 呼叫程式碼通常會透過呼叫其 init 函式來生成 NIT,因此負責釋放它。

返回值

寫入緩衝區的位元組數。 這不等於 NIT 的大小,因為在 TS 封裝期間需要更多空間來容納 TS 標頭。

struct vidtv_psi_eit_write_args

用於寫入 EIT 節的引數

定義:

struct vidtv_psi_eit_write_args {
    char *buf;
    u32 offset;
    struct vidtv_psi_table_eit *eit;
    u32 buf_sz;
    u8 *continuity_counter;
};

成員

buf

目標緩衝區。

offset

目標緩衝區的偏移量。

eit

指向 EIT 的指標

buf_sz

目標緩衝區的大小。

continuity_counter

指向 CC 的指標。 在每個新資料包上遞增。

u32 vidtv_psi_eit_write_into(struct vidtv_psi_eit_write_args *args)

將 EIT 作為 MPEG-TS 資料包寫入緩衝區。

引數

struct vidtv_psi_eit_write_args *args

struct vidtv_psi_nit_write_args 的一個例項

描述

此函式將 EIT 表的 MPEG TS 資料包寫入緩衝區。 呼叫程式碼通常會透過呼叫其 init 函式來生成 EIT,因此負責釋放它。

返回值

寫入緩衝區的位元組數。 這不等於 EIT 的大小,因為在 TS 封裝期間需要更多空間來容納 TS 標頭。

void vidtv_psi_eit_table_update_sec_len(struct vidtv_psi_table_eit *eit)

重新計算並更新 EIT 節長度。

引數

struct vidtv_psi_table_eit *eit

要更新長度的 EIT。

描述

這將遍歷表並累積其元件的長度,然後將其用於替換 “section_length” 欄位。

如果 section_length > EIT_MAX_SECTION_LEN,則操作失敗。

void vidtv_psi_eit_event_assign(struct vidtv_psi_table_eit *eit, struct vidtv_psi_table_eit_event *e)

將事件迴圈分配給 EIT。

引數

struct vidtv_psi_table_eit *eit

要分配給的 EIT。

struct vidtv_psi_table_eit_event *e

事件迴圈

描述

這將釋放表中的先前事件迴圈。 這會將流迴圈的所有權分配給表,即,當呼叫其銷燬函式時,該表將釋放此流迴圈。

struct vidtv_s302m_ctx

s302m 編碼器上下文。

定義:

struct vidtv_s302m_ctx {
    struct vidtv_encoder *enc;
    u32 frame_index;
    u32 au_count;
    int last_duration;
    unsigned int note_offset;
    enum musical_notes last_tone;
};

成員

enc

指向包含編碼器結構的指標。

frame_index

塊中的當前幀

au_count

到目前為止編碼的訪問單元總數

last_duration

當前播放的音調的持續時間

note_offset

在音符音調陣列中的位置

last_tone

當前播放的音調

struct vidtv_s302m_encoder_init_args

s302m 編碼器的引數。

定義:

struct vidtv_s302m_encoder_init_args {
    char *name;
    void *src_buf;
    u32 src_buf_sz;
    u16 es_pid;
    struct vidtv_encoder *sync;
    void (*last_sample_cb)(u32 sample_no);
    struct vidtv_encoder *head;
};

成員

name

用於標識此特定例項的名稱

src_buf

源緩衝區,如果此項為 NULL,則編碼器將預設為正弦波。

src_buf_sz

源緩衝區的大小。

es_pid

要使用的 MPEG 基本流 PID。

sync

嘗試將音訊與此影片編碼器同步,如果不是 NULL。

last_sample_cb

當編碼器用完資料時呼叫的回撥。

head

新增到此鏈

struct pcr_write_args

pcr_write_into 函式的引數。

定義:

struct pcr_write_args {
    void *dest_buf;
    u32 dest_offset;
    u16 pid;
    u32 buf_sz;
    u8 *continuity_counter;
    u64 pcr;
};

成員

dest_buf

要寫入的緩衝區。

dest_offset

緩衝區中的位元組偏移量。

pid

PCR 資料包的 TS PID。

buf_sz

緩衝區的位元組大小。

continuity_counter

TS continuity_counter。

pcr

來自系統時鐘的樣本。

struct null_packet_write_args

null_write_into 函式的引數

定義:

struct null_packet_write_args {
    void *dest_buf;
    u32 dest_offset;
    u32 buf_sz;
    u8 *continuity_counter;
};

成員

dest_buf

要寫入的緩衝區。

dest_offset

緩衝區中的位元組偏移量。

buf_sz

緩衝區的位元組大小。

continuity_counter

TS continuity_counter。

u32 vidtv_ts_null_write_into(struct null_packet_write_args args)

將 TS 空資料包寫入緩衝區。

引數

struct null_packet_write_args args

寫入時要使用的引數。

描述

此函式會將空資料包寫入緩衝區。 這通常用於填充 TS 流。

返回值

寫入緩衝區的位元組數。

u32 vidtv_ts_pcr_write_into(struct pcr_write_args args)

將 PCR 資料包寫入緩衝區。

引數

struct pcr_write_args args

寫入時要使用的引數。

描述

此函式會將 PCR 資料包寫入緩衝區。 這用於同步編碼器和解碼器之間的時鐘。

返回值

寫入緩衝區的位元組數。

struct vidtv_tuner_config

用於初始化調諧器的配置。

定義:

struct vidtv_tuner_config {
    struct dvb_frontend *fe;
    u32 mock_power_up_delay_msec;
    u32 mock_tune_delay_msec;
    u32 vidtv_valid_dvb_t_freqs[NUM_VALID_TUNER_FREQS];
    u32 vidtv_valid_dvb_c_freqs[NUM_VALID_TUNER_FREQS];
    u32 vidtv_valid_dvb_s_freqs[NUM_VALID_TUNER_FREQS];
    u8 max_frequency_shift_hz;
};

成員

fe

指向 vidtv_demod 分配的 dvb_frontend 結構的指標。

mock_power_up_delay_msec

模擬上電延遲。

mock_tune_delay_msec

模擬調諧延遲。

vidtv_valid_dvb_t_freqs

要模擬的有效 DVB-T 頻率。

vidtv_valid_dvb_c_freqs

要模擬的有效 DVB-C 頻率。

vidtv_valid_dvb_s_freqs

要模擬的有效 DVB-S 頻率。

max_frequency_shift_hz

調諧到頻道時允許的最大頻率偏移量 (HZ)

描述

用於初始化調諧器模組的配置,通常由橋驅動程式填充。 對於 vidtv,這由 vidtv_bridge 在探測調諧器模組之前填充。

u32 vidtv_memcpy(void *to, size_t to_offset, size_t to_size, const void *from, size_t len)

MPEG-TS 生成器使用的包裝例程,以避免超出輸出緩衝區。

引數

void *to

MPEG-TS 包將被複制到的起始元素。

size_t to_offset

要填充的 to 緩衝區的起始位置。

size_t to_size

to 緩衝區的大小。

const void *from

要複製的緩衝區的起始元素。

size_t len

要從 from 緩衝區複製到 to**+ **to_offset 緩衝區的元素數量。

注意:

真正的數字電視解調驅動程式不應具有 memcpy 包裝器。 我們在這裡使用它,因為在核心空間中模擬 MPEG-TS 生成需要格外小心。

返回值

返回寫入的位元組數

u32 vidtv_memset(void *to, size_t to_offset, size_t to_size, const int c, size_t len)

MPEG-TS 生成器使用的包裝例程,以避免超出輸出緩衝區。

引數

void *to

要設定的起始元素

size_t to_offset

要填充的 to 緩衝區的起始位置。

size_t to_size

to 緩衝區的大小。

const int c

用於設定記憶體的值。

size_t len

要從 from 緩衝區複製到 to**+ **to_offset 緩衝區的元素數量。

注意:

真正的數字電視解調驅動程式不應具有 memset 包裝器。 我們在這裡使用它,因為在核心空間中模擬 MPEG-TS 生成需要格外小心。

返回值

返回寫入的位元組數

struct vidtv_tuner_hardware_state

模擬調諧器硬體狀態

定義:

struct vidtv_tuner_hardware_state {
    bool asleep;
    u32 lock_status;
    u32 if_frequency;
    u32 tuned_frequency;
    u32 bandwidth;
};

成員

asleep

調諧器是否處於休眠狀態,即是否呼叫了 _sleep() 或 _suspend()。

lock_status

調諧器是否已成功鎖定請求的頻率。

if_frequency

調諧器的中頻。 為了模擬的目的而硬編碼。

tuned_frequency

實際調諧頻率。

bandwidth

實際頻寬。

描述

此結構旨在模擬調諧器硬體的狀態,就像我們有一個物理調諧器硬體一樣。

struct vidtv_tuner_dev

調諧器結構體

定義:

struct vidtv_tuner_dev {
    struct dvb_frontend *fe;
    struct vidtv_tuner_hardware_state hw_state;
    struct vidtv_tuner_config config;
};

成員

fe

指向 vidtv_demod 分配的 dvb_frontend 結構的指標

hw_state

一個用於模擬調諧器硬體狀態的結構體,就像我們有一個物理調諧器硬體一樣。

config

用於啟動調諧器模組的配置,通常由橋接驅動程式填充。 對於 vidtv,這由 vidtv_bridge 在探測調諧器模組之前填充。