1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Vidtv serves as a reference DVB driver and helps validate the existing APIs
4*4882a593Smuzhiyun * in the media subsystem. It can also aid developers working on userspace
5*4882a593Smuzhiyun * applications.
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * This file contains the code for an AES3 (also known as AES/EBU) encoder.
8*4882a593Smuzhiyun * It is based on EBU Tech 3250 and SMPTE 302M technical documents.
9*4882a593Smuzhiyun *
10*4882a593Smuzhiyun * This encoder currently supports 16bit AES3 subframes using 16bit signed
11*4882a593Smuzhiyun * integers.
12*4882a593Smuzhiyun *
13*4882a593Smuzhiyun * Note: AU stands for Access Unit, and AAU stands for Audio Access Unit
14*4882a593Smuzhiyun *
15*4882a593Smuzhiyun * Copyright (C) 2020 Daniel W. S. Almeida
16*4882a593Smuzhiyun */
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun #define pr_fmt(fmt) KBUILD_MODNAME ":%s, %d: " fmt, __func__, __LINE__
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun #include <linux/bug.h>
21*4882a593Smuzhiyun #include <linux/crc32.h>
22*4882a593Smuzhiyun #include <linux/fixp-arith.h>
23*4882a593Smuzhiyun #include <linux/jiffies.h>
24*4882a593Smuzhiyun #include <linux/kernel.h>
25*4882a593Smuzhiyun #include <linux/math64.h>
26*4882a593Smuzhiyun #include <linux/printk.h>
27*4882a593Smuzhiyun #include <linux/ratelimit.h>
28*4882a593Smuzhiyun #include <linux/slab.h>
29*4882a593Smuzhiyun #include <linux/string.h>
30*4882a593Smuzhiyun #include <linux/types.h>
31*4882a593Smuzhiyun #include <linux/vmalloc.h>
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun #include "vidtv_common.h"
34*4882a593Smuzhiyun #include "vidtv_encoder.h"
35*4882a593Smuzhiyun #include "vidtv_s302m.h"
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun #define S302M_SAMPLING_RATE_HZ 48000
38*4882a593Smuzhiyun #define PES_PRIVATE_STREAM_1 0xbd /* PES: private_stream_1 */
39*4882a593Smuzhiyun #define S302M_BLOCK_SZ 192
40*4882a593Smuzhiyun #define S302M_SIN_LUT_NUM_ELEM 1024
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun /* these are retrieved empirically from ffmpeg/libavcodec */
43*4882a593Smuzhiyun #define FF_S302M_DEFAULT_NUM_FRAMES 1115
44*4882a593Smuzhiyun #define FF_S302M_DEFAULT_PTS_INCREMENT 2090
45*4882a593Smuzhiyun #define FF_S302M_DEFAULT_PTS_OFFSET 100000
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun /* Used by the tone generator: number of samples for PI */
48*4882a593Smuzhiyun #define PI 180
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun static const u8 reverse[256] = {
51*4882a593Smuzhiyun /* from ffmpeg */
52*4882a593Smuzhiyun 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0,
53*4882a593Smuzhiyun 0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
54*4882a593Smuzhiyun 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 0x04, 0x84, 0x44, 0xC4,
55*4882a593Smuzhiyun 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
56*4882a593Smuzhiyun 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC,
57*4882a593Smuzhiyun 0x3C, 0xBC, 0x7C, 0xFC, 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
58*4882a593Smuzhiyun 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, 0x0A, 0x8A, 0x4A, 0xCA,
59*4882a593Smuzhiyun 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
60*4882a593Smuzhiyun 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6,
61*4882a593Smuzhiyun 0x36, 0xB6, 0x76, 0xF6, 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
62*4882a593Smuzhiyun 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, 0x01, 0x81, 0x41, 0xC1,
63*4882a593Smuzhiyun 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
64*4882a593Smuzhiyun 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9,
65*4882a593Smuzhiyun 0x39, 0xB9, 0x79, 0xF9, 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
66*4882a593Smuzhiyun 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, 0x0D, 0x8D, 0x4D, 0xCD,
67*4882a593Smuzhiyun 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
68*4882a593Smuzhiyun 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3,
69*4882a593Smuzhiyun 0x33, 0xB3, 0x73, 0xF3, 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
70*4882a593Smuzhiyun 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, 0x07, 0x87, 0x47, 0xC7,
71*4882a593Smuzhiyun 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
72*4882a593Smuzhiyun 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF,
73*4882a593Smuzhiyun 0x3F, 0xBF, 0x7F, 0xFF,
74*4882a593Smuzhiyun };
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun struct tone_duration {
77*4882a593Smuzhiyun enum musical_notes note;
78*4882a593Smuzhiyun int duration;
79*4882a593Smuzhiyun };
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun #define COMPASS 100 /* beats per minute */
82*4882a593Smuzhiyun static const struct tone_duration beethoven_fur_elise[] = {
83*4882a593Smuzhiyun { NOTE_SILENT, 512},
84*4882a593Smuzhiyun { NOTE_E_6, 128}, { NOTE_DS_6, 128}, { NOTE_E_6, 128},
85*4882a593Smuzhiyun { NOTE_DS_6, 128}, { NOTE_E_6, 128}, { NOTE_B_5, 128},
86*4882a593Smuzhiyun { NOTE_D_6, 128}, { NOTE_C_6, 128}, { NOTE_A_3, 128},
87*4882a593Smuzhiyun { NOTE_E_4, 128}, { NOTE_A_4, 128}, { NOTE_C_5, 128},
88*4882a593Smuzhiyun { NOTE_E_5, 128}, { NOTE_A_5, 128}, { NOTE_E_3, 128},
89*4882a593Smuzhiyun { NOTE_E_4, 128}, { NOTE_GS_4, 128}, { NOTE_E_5, 128},
90*4882a593Smuzhiyun { NOTE_GS_5, 128}, { NOTE_B_5, 128}, { NOTE_A_3, 128},
91*4882a593Smuzhiyun { NOTE_E_4, 128}, { NOTE_A_4, 128}, { NOTE_E_5, 128},
92*4882a593Smuzhiyun { NOTE_E_6, 128}, { NOTE_DS_6, 128}, { NOTE_E_6, 128},
93*4882a593Smuzhiyun { NOTE_DS_6, 128}, { NOTE_E_6, 128}, { NOTE_B_5, 128},
94*4882a593Smuzhiyun { NOTE_D_6, 128}, { NOTE_C_6, 128}, { NOTE_A_3, 128},
95*4882a593Smuzhiyun { NOTE_E_4, 128}, { NOTE_A_4, 128}, { NOTE_C_5, 128},
96*4882a593Smuzhiyun { NOTE_E_5, 128}, { NOTE_A_5, 128}, { NOTE_E_3, 128},
97*4882a593Smuzhiyun { NOTE_E_4, 128}, { NOTE_GS_4, 128}, { NOTE_E_5, 128},
98*4882a593Smuzhiyun { NOTE_C_6, 128}, { NOTE_B_5, 128}, { NOTE_A_3, 128},
99*4882a593Smuzhiyun { NOTE_E_4, 128}, { NOTE_A_4, 128}, { NOTE_SILENT, 128},
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun { NOTE_E_6, 128}, { NOTE_DS_6, 128}, { NOTE_E_6, 128},
102*4882a593Smuzhiyun { NOTE_DS_6, 128}, { NOTE_E_6, 128}, { NOTE_B_5, 128},
103*4882a593Smuzhiyun { NOTE_D_6, 128}, { NOTE_C_6, 128}, { NOTE_A_3, 128},
104*4882a593Smuzhiyun { NOTE_E_4, 128}, { NOTE_A_4, 128}, { NOTE_C_5, 128},
105*4882a593Smuzhiyun { NOTE_E_5, 128}, { NOTE_A_5, 128}, { NOTE_E_3, 128},
106*4882a593Smuzhiyun { NOTE_E_4, 128}, { NOTE_GS_4, 128}, { NOTE_E_5, 128},
107*4882a593Smuzhiyun { NOTE_GS_5, 128}, { NOTE_B_5, 128}, { NOTE_A_3, 128},
108*4882a593Smuzhiyun { NOTE_E_4, 128}, { NOTE_A_4, 128}, { NOTE_E_5, 128},
109*4882a593Smuzhiyun { NOTE_E_6, 128}, { NOTE_DS_6, 128}, { NOTE_E_6, 128},
110*4882a593Smuzhiyun { NOTE_DS_6, 128}, { NOTE_E_6, 128}, { NOTE_B_5, 128},
111*4882a593Smuzhiyun { NOTE_D_6, 128}, { NOTE_C_6, 128}, { NOTE_A_3, 128},
112*4882a593Smuzhiyun { NOTE_E_4, 128}, { NOTE_A_4, 128}, { NOTE_C_5, 128},
113*4882a593Smuzhiyun { NOTE_E_5, 128}, { NOTE_A_5, 128}, { NOTE_E_3, 128},
114*4882a593Smuzhiyun { NOTE_E_4, 128}, { NOTE_GS_4, 128}, { NOTE_E_5, 128},
115*4882a593Smuzhiyun { NOTE_C_6, 128}, { NOTE_B_5, 128}, { NOTE_A_3, 128},
116*4882a593Smuzhiyun { NOTE_E_4, 128}, { NOTE_A_4, 128}, { NOTE_B_4, 128},
117*4882a593Smuzhiyun { NOTE_C_5, 128}, { NOTE_D_5, 128}, { NOTE_C_4, 128},
118*4882a593Smuzhiyun { NOTE_G_4, 128}, { NOTE_C_5, 128}, { NOTE_G_4, 128},
119*4882a593Smuzhiyun { NOTE_F_5, 128}, { NOTE_E_5, 128}, { NOTE_G_3, 128},
120*4882a593Smuzhiyun { NOTE_G_4, 128}, { NOTE_B_3, 128}, { NOTE_F_4, 128},
121*4882a593Smuzhiyun { NOTE_E_5, 128}, { NOTE_D_5, 128}, { NOTE_A_3, 128},
122*4882a593Smuzhiyun { NOTE_E_4, 128}, { NOTE_A_4, 128}, { NOTE_E_4, 128},
123*4882a593Smuzhiyun { NOTE_D_5, 128}, { NOTE_C_5, 128}, { NOTE_E_3, 128},
124*4882a593Smuzhiyun { NOTE_E_4, 128}, { NOTE_E_5, 128}, { NOTE_E_5, 128},
125*4882a593Smuzhiyun { NOTE_E_6, 128}, { NOTE_E_5, 128}, { NOTE_E_6, 128},
126*4882a593Smuzhiyun { NOTE_E_5, 128}, { NOTE_E_5, 128}, { NOTE_DS_5, 128},
127*4882a593Smuzhiyun { NOTE_E_5, 128}, { NOTE_DS_6, 128}, { NOTE_E_6, 128},
128*4882a593Smuzhiyun { NOTE_DS_5, 128}, { NOTE_E_5, 128}, { NOTE_DS_6, 128},
129*4882a593Smuzhiyun { NOTE_E_6, 128}, { NOTE_DS_6, 128}, { NOTE_E_6, 128},
130*4882a593Smuzhiyun { NOTE_DS_6, 128}, { NOTE_E_6, 128}, { NOTE_B_5, 128},
131*4882a593Smuzhiyun { NOTE_D_6, 128}, { NOTE_C_6, 128}, { NOTE_A_3, 128},
132*4882a593Smuzhiyun { NOTE_E_4, 128}, { NOTE_A_4, 128}, { NOTE_C_5, 128},
133*4882a593Smuzhiyun { NOTE_E_5, 128}, { NOTE_A_5, 128}, { NOTE_E_3, 128},
134*4882a593Smuzhiyun { NOTE_E_4, 128}, { NOTE_GS_4, 128}, { NOTE_E_5, 128},
135*4882a593Smuzhiyun { NOTE_GS_5, 128}, { NOTE_B_5, 128}, { NOTE_A_3, 128},
136*4882a593Smuzhiyun { NOTE_E_4, 128}, { NOTE_A_4, 128}, { NOTE_E_5, 128},
137*4882a593Smuzhiyun { NOTE_E_6, 128}, { NOTE_DS_6, 128}, { NOTE_E_6, 128},
138*4882a593Smuzhiyun { NOTE_DS_6, 128}, { NOTE_E_6, 128}, { NOTE_B_5, 128},
139*4882a593Smuzhiyun { NOTE_D_6, 128}, { NOTE_C_6, 128}, { NOTE_A_3, 128},
140*4882a593Smuzhiyun { NOTE_E_4, 128}, { NOTE_A_4, 128}, { NOTE_C_5, 128},
141*4882a593Smuzhiyun { NOTE_E_5, 128}, { NOTE_A_5, 128}, { NOTE_E_3, 128},
142*4882a593Smuzhiyun { NOTE_E_4, 128}, { NOTE_GS_4, 128}, { NOTE_E_5, 128},
143*4882a593Smuzhiyun { NOTE_C_6, 128}, { NOTE_B_5, 128}, { NOTE_A_5, 512},
144*4882a593Smuzhiyun { NOTE_SILENT, 256},
145*4882a593Smuzhiyun };
146*4882a593Smuzhiyun
vidtv_s302m_access_unit_init(struct vidtv_access_unit * head)147*4882a593Smuzhiyun static struct vidtv_access_unit *vidtv_s302m_access_unit_init(struct vidtv_access_unit *head)
148*4882a593Smuzhiyun {
149*4882a593Smuzhiyun struct vidtv_access_unit *au;
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun au = kzalloc(sizeof(*au), GFP_KERNEL);
152*4882a593Smuzhiyun if (!au)
153*4882a593Smuzhiyun return NULL;
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun if (head) {
156*4882a593Smuzhiyun while (head->next)
157*4882a593Smuzhiyun head = head->next;
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun head->next = au;
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun return au;
163*4882a593Smuzhiyun }
164*4882a593Smuzhiyun
vidtv_s302m_access_unit_destroy(struct vidtv_encoder * e)165*4882a593Smuzhiyun static void vidtv_s302m_access_unit_destroy(struct vidtv_encoder *e)
166*4882a593Smuzhiyun {
167*4882a593Smuzhiyun struct vidtv_access_unit *head = e->access_units;
168*4882a593Smuzhiyun struct vidtv_access_unit *tmp = NULL;
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun while (head) {
171*4882a593Smuzhiyun tmp = head;
172*4882a593Smuzhiyun head = head->next;
173*4882a593Smuzhiyun kfree(tmp);
174*4882a593Smuzhiyun }
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun e->access_units = NULL;
177*4882a593Smuzhiyun }
178*4882a593Smuzhiyun
vidtv_s302m_alloc_au(struct vidtv_encoder * e)179*4882a593Smuzhiyun static void vidtv_s302m_alloc_au(struct vidtv_encoder *e)
180*4882a593Smuzhiyun {
181*4882a593Smuzhiyun struct vidtv_access_unit *sync_au = NULL;
182*4882a593Smuzhiyun struct vidtv_access_unit *temp = NULL;
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun if (e->sync && e->sync->is_video_encoder) {
185*4882a593Smuzhiyun sync_au = e->sync->access_units;
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun while (sync_au) {
188*4882a593Smuzhiyun temp = vidtv_s302m_access_unit_init(e->access_units);
189*4882a593Smuzhiyun if (!e->access_units)
190*4882a593Smuzhiyun e->access_units = temp;
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun sync_au = sync_au->next;
193*4882a593Smuzhiyun }
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun return;
196*4882a593Smuzhiyun }
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun e->access_units = vidtv_s302m_access_unit_init(NULL);
199*4882a593Smuzhiyun }
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun static void
vidtv_s302m_compute_sample_count_from_video(struct vidtv_encoder * e)202*4882a593Smuzhiyun vidtv_s302m_compute_sample_count_from_video(struct vidtv_encoder *e)
203*4882a593Smuzhiyun {
204*4882a593Smuzhiyun struct vidtv_access_unit *sync_au = e->sync->access_units;
205*4882a593Smuzhiyun struct vidtv_access_unit *au = e->access_units;
206*4882a593Smuzhiyun u32 sample_duration_usecs;
207*4882a593Smuzhiyun u32 vau_duration_usecs;
208*4882a593Smuzhiyun u32 s;
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun vau_duration_usecs = USEC_PER_SEC / e->sync->sampling_rate_hz;
211*4882a593Smuzhiyun sample_duration_usecs = USEC_PER_SEC / e->sampling_rate_hz;
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun while (au && sync_au) {
214*4882a593Smuzhiyun s = DIV_ROUND_UP(vau_duration_usecs, sample_duration_usecs);
215*4882a593Smuzhiyun au->num_samples = s;
216*4882a593Smuzhiyun au = au->next;
217*4882a593Smuzhiyun sync_au = sync_au->next;
218*4882a593Smuzhiyun }
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun
vidtv_s302m_compute_pts_from_video(struct vidtv_encoder * e)221*4882a593Smuzhiyun static void vidtv_s302m_compute_pts_from_video(struct vidtv_encoder *e)
222*4882a593Smuzhiyun {
223*4882a593Smuzhiyun struct vidtv_access_unit *au = e->access_units;
224*4882a593Smuzhiyun struct vidtv_access_unit *sync_au = e->sync->access_units;
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun /* use the same pts from the video access unit*/
227*4882a593Smuzhiyun while (au && sync_au) {
228*4882a593Smuzhiyun au->pts = sync_au->pts;
229*4882a593Smuzhiyun au = au->next;
230*4882a593Smuzhiyun sync_au = sync_au->next;
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun }
233*4882a593Smuzhiyun
vidtv_s302m_get_sample(struct vidtv_encoder * e)234*4882a593Smuzhiyun static u16 vidtv_s302m_get_sample(struct vidtv_encoder *e)
235*4882a593Smuzhiyun {
236*4882a593Smuzhiyun u16 sample;
237*4882a593Smuzhiyun int pos;
238*4882a593Smuzhiyun struct vidtv_s302m_ctx *ctx = e->ctx;
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun if (!e->src_buf) {
241*4882a593Smuzhiyun /*
242*4882a593Smuzhiyun * Simple tone generator: play the tones at the
243*4882a593Smuzhiyun * beethoven_fur_elise array.
244*4882a593Smuzhiyun */
245*4882a593Smuzhiyun if (ctx->last_duration <= 0) {
246*4882a593Smuzhiyun if (e->src_buf_offset >= ARRAY_SIZE(beethoven_fur_elise))
247*4882a593Smuzhiyun e->src_buf_offset = 0;
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun ctx->last_tone = beethoven_fur_elise[e->src_buf_offset].note;
250*4882a593Smuzhiyun ctx->last_duration = beethoven_fur_elise[e->src_buf_offset].duration *
251*4882a593Smuzhiyun S302M_SAMPLING_RATE_HZ / COMPASS / 5;
252*4882a593Smuzhiyun e->src_buf_offset++;
253*4882a593Smuzhiyun ctx->note_offset = 0;
254*4882a593Smuzhiyun } else {
255*4882a593Smuzhiyun ctx->last_duration--;
256*4882a593Smuzhiyun }
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun /* Handle pause notes */
259*4882a593Smuzhiyun if (!ctx->last_tone)
260*4882a593Smuzhiyun return 0x8000;
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun pos = (2 * PI * ctx->note_offset * ctx->last_tone) / S302M_SAMPLING_RATE_HZ;
263*4882a593Smuzhiyun ctx->note_offset++;
264*4882a593Smuzhiyun
265*4882a593Smuzhiyun return (fixp_sin32(pos % (2 * PI)) >> 16) + 0x8000;
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun /* bug somewhere */
269*4882a593Smuzhiyun if (e->src_buf_offset > e->src_buf_sz) {
270*4882a593Smuzhiyun pr_err_ratelimited("overflow detected: %d > %d, wrapping.\n",
271*4882a593Smuzhiyun e->src_buf_offset,
272*4882a593Smuzhiyun e->src_buf_sz);
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun e->src_buf_offset = 0;
275*4882a593Smuzhiyun }
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun if (e->src_buf_offset >= e->src_buf_sz) {
278*4882a593Smuzhiyun /* let the source know we are out of data */
279*4882a593Smuzhiyun if (e->last_sample_cb)
280*4882a593Smuzhiyun e->last_sample_cb(e->sample_count);
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun e->src_buf_offset = 0;
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun sample = *(u16 *)(e->src_buf + e->src_buf_offset);
286*4882a593Smuzhiyun
287*4882a593Smuzhiyun return sample;
288*4882a593Smuzhiyun }
289*4882a593Smuzhiyun
vidtv_s302m_write_frame(struct vidtv_encoder * e,u16 sample)290*4882a593Smuzhiyun static u32 vidtv_s302m_write_frame(struct vidtv_encoder *e,
291*4882a593Smuzhiyun u16 sample)
292*4882a593Smuzhiyun {
293*4882a593Smuzhiyun struct vidtv_s302m_ctx *ctx = e->ctx;
294*4882a593Smuzhiyun struct vidtv_s302m_frame_16 f = {};
295*4882a593Smuzhiyun u32 nbytes = 0;
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun /* from ffmpeg: see s302enc.c */
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun u8 vucf = ctx->frame_index == 0 ? 0x10 : 0;
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun f.data[0] = sample & 0xFF;
302*4882a593Smuzhiyun f.data[1] = (sample & 0xFF00) >> 8;
303*4882a593Smuzhiyun f.data[2] = ((sample & 0x0F) << 4) | vucf;
304*4882a593Smuzhiyun f.data[3] = (sample & 0x0FF0) >> 4;
305*4882a593Smuzhiyun f.data[4] = (sample & 0xF000) >> 12;
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun f.data[0] = reverse[f.data[0]];
308*4882a593Smuzhiyun f.data[1] = reverse[f.data[1]];
309*4882a593Smuzhiyun f.data[2] = reverse[f.data[2]];
310*4882a593Smuzhiyun f.data[3] = reverse[f.data[3]];
311*4882a593Smuzhiyun f.data[4] = reverse[f.data[4]];
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun nbytes += vidtv_memcpy(e->encoder_buf,
314*4882a593Smuzhiyun e->encoder_buf_offset,
315*4882a593Smuzhiyun VIDTV_S302M_BUF_SZ,
316*4882a593Smuzhiyun &f,
317*4882a593Smuzhiyun sizeof(f));
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun e->encoder_buf_offset += nbytes;
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun ctx->frame_index++;
322*4882a593Smuzhiyun if (ctx->frame_index >= S302M_BLOCK_SZ)
323*4882a593Smuzhiyun ctx->frame_index = 0;
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun return nbytes;
326*4882a593Smuzhiyun }
327*4882a593Smuzhiyun
vidtv_s302m_write_h(struct vidtv_encoder * e,u32 p_sz)328*4882a593Smuzhiyun static u32 vidtv_s302m_write_h(struct vidtv_encoder *e, u32 p_sz)
329*4882a593Smuzhiyun {
330*4882a593Smuzhiyun struct vidtv_smpte_s302m_es h = {};
331*4882a593Smuzhiyun u32 nbytes = 0;
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun /* 2 channels, ident: 0, 16 bits per sample */
334*4882a593Smuzhiyun h.bitfield = cpu_to_be32((p_sz << 16));
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun nbytes += vidtv_memcpy(e->encoder_buf,
337*4882a593Smuzhiyun e->encoder_buf_offset,
338*4882a593Smuzhiyun e->encoder_buf_sz,
339*4882a593Smuzhiyun &h,
340*4882a593Smuzhiyun sizeof(h));
341*4882a593Smuzhiyun
342*4882a593Smuzhiyun e->encoder_buf_offset += nbytes;
343*4882a593Smuzhiyun return nbytes;
344*4882a593Smuzhiyun }
345*4882a593Smuzhiyun
vidtv_s302m_write_frames(struct vidtv_encoder * e)346*4882a593Smuzhiyun static void vidtv_s302m_write_frames(struct vidtv_encoder *e)
347*4882a593Smuzhiyun {
348*4882a593Smuzhiyun struct vidtv_access_unit *au = e->access_units;
349*4882a593Smuzhiyun struct vidtv_s302m_ctx *ctx = e->ctx;
350*4882a593Smuzhiyun u32 nbytes_per_unit = 0;
351*4882a593Smuzhiyun u32 nbytes = 0;
352*4882a593Smuzhiyun u32 au_sz = 0;
353*4882a593Smuzhiyun u16 sample;
354*4882a593Smuzhiyun u32 j;
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun while (au) {
357*4882a593Smuzhiyun au_sz = au->num_samples *
358*4882a593Smuzhiyun sizeof(struct vidtv_s302m_frame_16);
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun nbytes_per_unit = vidtv_s302m_write_h(e, au_sz);
361*4882a593Smuzhiyun
362*4882a593Smuzhiyun for (j = 0; j < au->num_samples; ++j) {
363*4882a593Smuzhiyun sample = vidtv_s302m_get_sample(e);
364*4882a593Smuzhiyun nbytes_per_unit += vidtv_s302m_write_frame(e, sample);
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun if (e->src_buf)
367*4882a593Smuzhiyun e->src_buf_offset += sizeof(u16);
368*4882a593Smuzhiyun
369*4882a593Smuzhiyun e->sample_count++;
370*4882a593Smuzhiyun }
371*4882a593Smuzhiyun
372*4882a593Smuzhiyun au->nbytes = nbytes_per_unit;
373*4882a593Smuzhiyun
374*4882a593Smuzhiyun if (au_sz + sizeof(struct vidtv_smpte_s302m_es) != nbytes_per_unit) {
375*4882a593Smuzhiyun pr_warn_ratelimited("write size was %u, expected %zu\n",
376*4882a593Smuzhiyun nbytes_per_unit,
377*4882a593Smuzhiyun au_sz + sizeof(struct vidtv_smpte_s302m_es));
378*4882a593Smuzhiyun }
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun nbytes += nbytes_per_unit;
381*4882a593Smuzhiyun au->offset = nbytes - nbytes_per_unit;
382*4882a593Smuzhiyun
383*4882a593Smuzhiyun nbytes_per_unit = 0;
384*4882a593Smuzhiyun ctx->au_count++;
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun au = au->next;
387*4882a593Smuzhiyun }
388*4882a593Smuzhiyun }
389*4882a593Smuzhiyun
vidtv_s302m_encode(struct vidtv_encoder * e)390*4882a593Smuzhiyun static void *vidtv_s302m_encode(struct vidtv_encoder *e)
391*4882a593Smuzhiyun {
392*4882a593Smuzhiyun struct vidtv_s302m_ctx *ctx = e->ctx;
393*4882a593Smuzhiyun
394*4882a593Smuzhiyun /*
395*4882a593Smuzhiyun * According to SMPTE 302M, an audio access unit is specified as those
396*4882a593Smuzhiyun * AES3 words that are associated with a corresponding video frame.
397*4882a593Smuzhiyun * Therefore, there is one audio access unit for every video access unit
398*4882a593Smuzhiyun * in the corresponding video encoder ('sync'), using the same values
399*4882a593Smuzhiyun * for PTS as used by the video encoder.
400*4882a593Smuzhiyun *
401*4882a593Smuzhiyun * Assuming that it is also possible to send audio without any
402*4882a593Smuzhiyun * associated video, as in a radio-like service, a single audio access unit
403*4882a593Smuzhiyun * is created with values for 'num_samples' and 'pts' taken empirically from
404*4882a593Smuzhiyun * ffmpeg
405*4882a593Smuzhiyun */
406*4882a593Smuzhiyun
407*4882a593Smuzhiyun vidtv_s302m_access_unit_destroy(e);
408*4882a593Smuzhiyun vidtv_s302m_alloc_au(e);
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun if (e->sync && e->sync->is_video_encoder) {
411*4882a593Smuzhiyun vidtv_s302m_compute_sample_count_from_video(e);
412*4882a593Smuzhiyun vidtv_s302m_compute_pts_from_video(e);
413*4882a593Smuzhiyun } else {
414*4882a593Smuzhiyun e->access_units->num_samples = FF_S302M_DEFAULT_NUM_FRAMES;
415*4882a593Smuzhiyun e->access_units->pts = (ctx->au_count * FF_S302M_DEFAULT_PTS_INCREMENT) +
416*4882a593Smuzhiyun FF_S302M_DEFAULT_PTS_OFFSET;
417*4882a593Smuzhiyun }
418*4882a593Smuzhiyun
419*4882a593Smuzhiyun vidtv_s302m_write_frames(e);
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun return e->encoder_buf;
422*4882a593Smuzhiyun }
423*4882a593Smuzhiyun
vidtv_s302m_clear(struct vidtv_encoder * e)424*4882a593Smuzhiyun static u32 vidtv_s302m_clear(struct vidtv_encoder *e)
425*4882a593Smuzhiyun {
426*4882a593Smuzhiyun struct vidtv_access_unit *au = e->access_units;
427*4882a593Smuzhiyun u32 count = 0;
428*4882a593Smuzhiyun
429*4882a593Smuzhiyun while (au) {
430*4882a593Smuzhiyun count++;
431*4882a593Smuzhiyun au = au->next;
432*4882a593Smuzhiyun }
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun vidtv_s302m_access_unit_destroy(e);
435*4882a593Smuzhiyun memset(e->encoder_buf, 0, VIDTV_S302M_BUF_SZ);
436*4882a593Smuzhiyun e->encoder_buf_offset = 0;
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun return count;
439*4882a593Smuzhiyun }
440*4882a593Smuzhiyun
441*4882a593Smuzhiyun struct vidtv_encoder
vidtv_s302m_encoder_init(struct vidtv_s302m_encoder_init_args args)442*4882a593Smuzhiyun *vidtv_s302m_encoder_init(struct vidtv_s302m_encoder_init_args args)
443*4882a593Smuzhiyun {
444*4882a593Smuzhiyun u32 priv_sz = sizeof(struct vidtv_s302m_ctx);
445*4882a593Smuzhiyun struct vidtv_s302m_ctx *ctx;
446*4882a593Smuzhiyun struct vidtv_encoder *e;
447*4882a593Smuzhiyun
448*4882a593Smuzhiyun e = kzalloc(sizeof(*e), GFP_KERNEL);
449*4882a593Smuzhiyun if (!e)
450*4882a593Smuzhiyun return NULL;
451*4882a593Smuzhiyun
452*4882a593Smuzhiyun e->id = S302M;
453*4882a593Smuzhiyun
454*4882a593Smuzhiyun if (args.name)
455*4882a593Smuzhiyun e->name = kstrdup(args.name, GFP_KERNEL);
456*4882a593Smuzhiyun
457*4882a593Smuzhiyun e->encoder_buf = vzalloc(VIDTV_S302M_BUF_SZ);
458*4882a593Smuzhiyun if (!e->encoder_buf)
459*4882a593Smuzhiyun goto out_kfree_e;
460*4882a593Smuzhiyun
461*4882a593Smuzhiyun e->encoder_buf_sz = VIDTV_S302M_BUF_SZ;
462*4882a593Smuzhiyun e->encoder_buf_offset = 0;
463*4882a593Smuzhiyun
464*4882a593Smuzhiyun e->sample_count = 0;
465*4882a593Smuzhiyun
466*4882a593Smuzhiyun e->src_buf = (args.src_buf) ? args.src_buf : NULL;
467*4882a593Smuzhiyun e->src_buf_sz = (args.src_buf) ? args.src_buf_sz : 0;
468*4882a593Smuzhiyun e->src_buf_offset = 0;
469*4882a593Smuzhiyun
470*4882a593Smuzhiyun e->is_video_encoder = false;
471*4882a593Smuzhiyun
472*4882a593Smuzhiyun ctx = kzalloc(priv_sz, GFP_KERNEL);
473*4882a593Smuzhiyun if (!ctx)
474*4882a593Smuzhiyun goto out_kfree_buf;
475*4882a593Smuzhiyun
476*4882a593Smuzhiyun e->ctx = ctx;
477*4882a593Smuzhiyun ctx->last_duration = 0;
478*4882a593Smuzhiyun
479*4882a593Smuzhiyun e->encode = vidtv_s302m_encode;
480*4882a593Smuzhiyun e->clear = vidtv_s302m_clear;
481*4882a593Smuzhiyun
482*4882a593Smuzhiyun e->es_pid = cpu_to_be16(args.es_pid);
483*4882a593Smuzhiyun e->stream_id = cpu_to_be16(PES_PRIVATE_STREAM_1);
484*4882a593Smuzhiyun
485*4882a593Smuzhiyun e->sync = args.sync;
486*4882a593Smuzhiyun e->sampling_rate_hz = S302M_SAMPLING_RATE_HZ;
487*4882a593Smuzhiyun
488*4882a593Smuzhiyun e->last_sample_cb = args.last_sample_cb;
489*4882a593Smuzhiyun
490*4882a593Smuzhiyun e->destroy = vidtv_s302m_encoder_destroy;
491*4882a593Smuzhiyun
492*4882a593Smuzhiyun if (args.head) {
493*4882a593Smuzhiyun while (args.head->next)
494*4882a593Smuzhiyun args.head = args.head->next;
495*4882a593Smuzhiyun
496*4882a593Smuzhiyun args.head->next = e;
497*4882a593Smuzhiyun }
498*4882a593Smuzhiyun
499*4882a593Smuzhiyun e->next = NULL;
500*4882a593Smuzhiyun
501*4882a593Smuzhiyun return e;
502*4882a593Smuzhiyun
503*4882a593Smuzhiyun out_kfree_buf:
504*4882a593Smuzhiyun kfree(e->encoder_buf);
505*4882a593Smuzhiyun
506*4882a593Smuzhiyun out_kfree_e:
507*4882a593Smuzhiyun kfree(e->name);
508*4882a593Smuzhiyun kfree(e);
509*4882a593Smuzhiyun return NULL;
510*4882a593Smuzhiyun }
511*4882a593Smuzhiyun
vidtv_s302m_encoder_destroy(struct vidtv_encoder * e)512*4882a593Smuzhiyun void vidtv_s302m_encoder_destroy(struct vidtv_encoder *e)
513*4882a593Smuzhiyun {
514*4882a593Smuzhiyun if (e->id != S302M) {
515*4882a593Smuzhiyun pr_err_ratelimited("Encoder type mismatch, skipping.\n");
516*4882a593Smuzhiyun return;
517*4882a593Smuzhiyun }
518*4882a593Smuzhiyun
519*4882a593Smuzhiyun vidtv_s302m_access_unit_destroy(e);
520*4882a593Smuzhiyun kfree(e->name);
521*4882a593Smuzhiyun vfree(e->encoder_buf);
522*4882a593Smuzhiyun kfree(e->ctx);
523*4882a593Smuzhiyun kfree(e);
524*4882a593Smuzhiyun }
525