Skip to content

Commit 163d72a

Browse files
committed
media: vidtv: avoid copying data for PES structs
Minimize the number of data copies and initialization at the code, passing them as pointers instead of duplicating the data. The only case where we're keeping the data copy is at vidtv_pes_write_h(), as it needs a copy of the passed arguments. On such case, we're being more explicit. Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
1 parent 0a33ab1 commit 163d72a

3 files changed

Lines changed: 102 additions & 108 deletions

File tree

drivers/media/test-drivers/vidtv/vidtv_mux.c

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -270,22 +270,28 @@ static u32 vidtv_mux_packetize_access_units(struct vidtv_mux *m,
270270
struct vidtv_encoder *e)
271271
{
272272
u32 nbytes = 0;
273-
274-
struct pes_write_args args = {};
273+
struct pes_write_args args = {
274+
.dest_buf = m->mux_buf,
275+
.dest_buf_sz = m->mux_buf_sz,
276+
.pid = be16_to_cpu(e->es_pid),
277+
.encoder_id = e->id,
278+
.stream_id = be16_to_cpu(e->stream_id),
279+
.send_pts = true, /* forbidden value '01'... */
280+
.send_dts = false, /* ...for PTS_DTS flags */
281+
};
275282
u32 initial_offset = m->mux_buf_offset;
276283
struct vidtv_access_unit *au = e->access_units;
277-
278284
u8 *buf = NULL;
279-
struct vidtv_mux_pid_ctx *pid_ctx = vidtv_mux_create_pid_ctx_once(m,
280-
be16_to_cpu(e->es_pid));
285+
struct vidtv_mux_pid_ctx *pid_ctx;
281286

282-
args.dest_buf = m->mux_buf;
283-
args.dest_buf_sz = m->mux_buf_sz;
284-
args.pid = be16_to_cpu(e->es_pid);
285-
args.encoder_id = e->id;
287+
/* see SMPTE 302M clause 6.4 */
288+
if (args.encoder_id == S302M) {
289+
args.send_dts = false;
290+
args.send_pts = true;
291+
}
292+
293+
pid_ctx = vidtv_mux_create_pid_ctx_once(m, be16_to_cpu(e->es_pid));
286294
args.continuity_counter = &pid_ctx->cc;
287-
args.stream_id = be16_to_cpu(e->stream_id);
288-
args.send_pts = true;
289295

290296
while (au) {
291297
buf = e->encoder_buf + au->offset;
@@ -295,7 +301,7 @@ static u32 vidtv_mux_packetize_access_units(struct vidtv_mux *m,
295301
args.pts = au->pts;
296302
args.pcr = m->timing.clk;
297303

298-
m->mux_buf_offset += vidtv_pes_write_into(args);
304+
m->mux_buf_offset += vidtv_pes_write_into(&args);
299305

300306
au = au->next;
301307
}

drivers/media/test-drivers/vidtv/vidtv_pes.c

Lines changed: 83 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -56,28 +56,28 @@ static u32 vidtv_pes_h_get_len(bool send_pts, bool send_dts)
5656
return len;
5757
}
5858

59-
static u32 vidtv_pes_write_header_stuffing(struct pes_header_write_args args)
59+
static u32 vidtv_pes_write_header_stuffing(struct pes_header_write_args *args)
6060
{
6161
/*
6262
* This is a fixed 8-bit value equal to '0xFF' that can be inserted
6363
* by the encoder, for example to meet the requirements of the channel.
6464
* It is discarded by the decoder. No more than 32 stuffing bytes shall
6565
* be present in one PES packet header.
6666
*/
67-
if (args.n_pes_h_s_bytes > PES_HEADER_MAX_STUFFING_BYTES) {
67+
if (args->n_pes_h_s_bytes > PES_HEADER_MAX_STUFFING_BYTES) {
6868
pr_warn_ratelimited("More than %d stuffing bytes in PES packet header\n",
6969
PES_HEADER_MAX_STUFFING_BYTES);
70-
args.n_pes_h_s_bytes = PES_HEADER_MAX_STUFFING_BYTES;
70+
args->n_pes_h_s_bytes = PES_HEADER_MAX_STUFFING_BYTES;
7171
}
7272

73-
return vidtv_memset(args.dest_buf,
74-
args.dest_offset,
75-
args.dest_buf_sz,
73+
return vidtv_memset(args->dest_buf,
74+
args->dest_offset,
75+
args->dest_buf_sz,
7676
TS_FILL_BYTE,
77-
args.n_pes_h_s_bytes);
77+
args->n_pes_h_s_bytes);
7878
}
7979

80-
static u32 vidtv_pes_write_pts_dts(struct pes_header_write_args args)
80+
static u32 vidtv_pes_write_pts_dts(struct pes_header_write_args *args)
8181
{
8282
u32 nbytes = 0; /* the number of bytes written by this function */
8383

@@ -89,88 +89,89 @@ static u32 vidtv_pes_write_pts_dts(struct pes_header_write_args args)
8989
u64 mask2;
9090
u64 mask3;
9191

92-
if (!args.send_pts && args.send_dts)
92+
if (!args->send_pts && args->send_dts)
9393
return 0;
9494

9595
mask1 = GENMASK_ULL(32, 30);
9696
mask2 = GENMASK_ULL(29, 15);
9797
mask3 = GENMASK_ULL(14, 0);
9898

9999
/* see ISO/IEC 13818-1 : 2000 p. 32 */
100-
if (args.send_pts && args.send_dts) {
101-
pts_dts.pts1 = (0x3 << 4) | ((args.pts & mask1) >> 29) | 0x1;
102-
pts_dts.pts2 = cpu_to_be16(((args.pts & mask2) >> 14) | 0x1);
103-
pts_dts.pts3 = cpu_to_be16(((args.pts & mask3) << 1) | 0x1);
100+
if (args->send_pts && args->send_dts) {
101+
pts_dts.pts1 = (0x3 << 4) | ((args->pts & mask1) >> 29) | 0x1;
102+
pts_dts.pts2 = cpu_to_be16(((args->pts & mask2) >> 14) | 0x1);
103+
pts_dts.pts3 = cpu_to_be16(((args->pts & mask3) << 1) | 0x1);
104104

105-
pts_dts.dts1 = (0x1 << 4) | ((args.dts & mask1) >> 29) | 0x1;
106-
pts_dts.dts2 = cpu_to_be16(((args.dts & mask2) >> 14) | 0x1);
107-
pts_dts.dts3 = cpu_to_be16(((args.dts & mask3) << 1) | 0x1);
105+
pts_dts.dts1 = (0x1 << 4) | ((args->dts & mask1) >> 29) | 0x1;
106+
pts_dts.dts2 = cpu_to_be16(((args->dts & mask2) >> 14) | 0x1);
107+
pts_dts.dts3 = cpu_to_be16(((args->dts & mask3) << 1) | 0x1);
108108

109109
op = &pts_dts;
110110
op_sz = sizeof(pts_dts);
111111

112-
} else if (args.send_pts) {
113-
pts.pts1 = (0x1 << 5) | ((args.pts & mask1) >> 29) | 0x1;
114-
pts.pts2 = cpu_to_be16(((args.pts & mask2) >> 14) | 0x1);
115-
pts.pts3 = cpu_to_be16(((args.pts & mask3) << 1) | 0x1);
112+
} else if (args->send_pts) {
113+
pts.pts1 = (0x1 << 5) | ((args->pts & mask1) >> 29) | 0x1;
114+
pts.pts2 = cpu_to_be16(((args->pts & mask2) >> 14) | 0x1);
115+
pts.pts3 = cpu_to_be16(((args->pts & mask3) << 1) | 0x1);
116116

117117
op = &pts;
118118
op_sz = sizeof(pts);
119119
}
120120

121121
/* copy PTS/DTS optional */
122-
nbytes += vidtv_memcpy(args.dest_buf,
123-
args.dest_offset + nbytes,
124-
args.dest_buf_sz,
122+
nbytes += vidtv_memcpy(args->dest_buf,
123+
args->dest_offset + nbytes,
124+
args->dest_buf_sz,
125125
op,
126126
op_sz);
127127

128128
return nbytes;
129129
}
130130

131-
static u32 vidtv_pes_write_h(struct pes_header_write_args args)
131+
static u32 vidtv_pes_write_h(struct pes_header_write_args *args)
132132
{
133133
u32 nbytes = 0; /* the number of bytes written by this function */
134134

135135
struct vidtv_mpeg_pes pes_header = {};
136136
struct vidtv_pes_optional pes_optional = {};
137-
struct pes_header_write_args pts_dts_args = args;
138-
u32 stream_id = (args.encoder_id == S302M) ? PRIVATE_STREAM_1_ID : args.stream_id;
137+
struct pes_header_write_args pts_dts_args;
138+
u32 stream_id = (args->encoder_id == S302M) ? PRIVATE_STREAM_1_ID : args->stream_id;
139139
u16 pes_opt_bitfield = 0x01 << 15;
140140

141141
pes_header.bitfield = cpu_to_be32((PES_START_CODE_PREFIX << 8) | stream_id);
142142

143-
pes_header.length = cpu_to_be16(vidtv_pes_op_get_len(args.send_pts,
144-
args.send_dts) +
145-
args.access_unit_len);
143+
pes_header.length = cpu_to_be16(vidtv_pes_op_get_len(args->send_pts,
144+
args->send_dts) +
145+
args->access_unit_len);
146146

147-
if (args.send_pts && args.send_dts)
147+
if (args->send_pts && args->send_dts)
148148
pes_opt_bitfield |= (0x3 << 6);
149-
else if (args.send_pts)
149+
else if (args->send_pts)
150150
pes_opt_bitfield |= (0x1 << 7);
151151

152152
pes_optional.bitfield = cpu_to_be16(pes_opt_bitfield);
153-
pes_optional.length = vidtv_pes_op_get_len(args.send_pts, args.send_dts) +
154-
args.n_pes_h_s_bytes -
153+
pes_optional.length = vidtv_pes_op_get_len(args->send_pts, args->send_dts) +
154+
args->n_pes_h_s_bytes -
155155
sizeof(struct vidtv_pes_optional);
156156

157157
/* copy header */
158-
nbytes += vidtv_memcpy(args.dest_buf,
159-
args.dest_offset + nbytes,
160-
args.dest_buf_sz,
158+
nbytes += vidtv_memcpy(args->dest_buf,
159+
args->dest_offset + nbytes,
160+
args->dest_buf_sz,
161161
&pes_header,
162162
sizeof(pes_header));
163163

164164
/* copy optional header bits */
165-
nbytes += vidtv_memcpy(args.dest_buf,
166-
args.dest_offset + nbytes,
167-
args.dest_buf_sz,
165+
nbytes += vidtv_memcpy(args->dest_buf,
166+
args->dest_offset + nbytes,
167+
args->dest_buf_sz,
168168
&pes_optional,
169169
sizeof(pes_optional));
170170

171171
/* copy the timing information */
172-
pts_dts_args.dest_offset = args.dest_offset + nbytes;
173-
nbytes += vidtv_pes_write_pts_dts(pts_dts_args);
172+
pts_dts_args = *args;
173+
pts_dts_args.dest_offset = args->dest_offset + nbytes;
174+
nbytes += vidtv_pes_write_pts_dts(&pts_dts_args);
174175

175176
/* write any PES header stuffing */
176177
nbytes += vidtv_pes_write_header_stuffing(args);
@@ -299,14 +300,31 @@ static u32 vidtv_pes_write_ts_h(struct pes_ts_header_write_args args,
299300
return nbytes;
300301
}
301302

302-
u32 vidtv_pes_write_into(struct pes_write_args args)
303+
u32 vidtv_pes_write_into(struct pes_write_args *args)
303304
{
304-
u32 unaligned_bytes = (args.dest_offset % TS_PACKET_LEN);
305-
struct pes_ts_header_write_args ts_header_args = {};
306-
struct pes_header_write_args pes_header_args = {};
307-
u32 remaining_len = args.access_unit_len;
305+
u32 unaligned_bytes = (args->dest_offset % TS_PACKET_LEN);
306+
struct pes_ts_header_write_args ts_header_args = {
307+
.dest_buf = args->dest_buf,
308+
.dest_buf_sz = args->dest_buf_sz,
309+
.pid = args->pid,
310+
.pcr = args->pcr,
311+
.continuity_counter = args->continuity_counter,
312+
};
313+
struct pes_header_write_args pes_header_args = {
314+
.dest_buf = args->dest_buf,
315+
.dest_buf_sz = args->dest_buf_sz,
316+
.encoder_id = args->encoder_id,
317+
.send_pts = args->send_pts,
318+
.pts = args->pts,
319+
.send_dts = args->send_dts,
320+
.dts = args->dts,
321+
.stream_id = args->stream_id,
322+
.n_pes_h_s_bytes = args->n_pes_h_s_bytes,
323+
.access_unit_len = args->access_unit_len,
324+
};
325+
u32 remaining_len = args->access_unit_len;
308326
bool wrote_pes_header = false;
309-
u64 last_pcr = args.pcr;
327+
u64 last_pcr = args->pcr;
310328
bool need_pcr = true;
311329
u32 available_space;
312330
u32 payload_size;
@@ -317,25 +335,13 @@ u32 vidtv_pes_write_into(struct pes_write_args args)
317335
pr_warn_ratelimited("buffer is misaligned, while starting PES\n");
318336

319337
/* forcibly align and hope for the best */
320-
nbytes += vidtv_memset(args.dest_buf,
321-
args.dest_offset + nbytes,
322-
args.dest_buf_sz,
338+
nbytes += vidtv_memset(args->dest_buf,
339+
args->dest_offset + nbytes,
340+
args->dest_buf_sz,
323341
TS_FILL_BYTE,
324342
TS_PACKET_LEN - unaligned_bytes);
325343
}
326344

327-
if (args.send_dts && !args.send_pts) {
328-
pr_warn_ratelimited("forbidden value '01' for PTS_DTS flags\n");
329-
args.send_pts = true;
330-
args.pts = args.dts;
331-
}
332-
333-
/* see SMPTE 302M clause 6.4 */
334-
if (args.encoder_id == S302M) {
335-
args.send_dts = false;
336-
args.send_pts = true;
337-
}
338-
339345
while (remaining_len) {
340346
available_space = TS_PAYLOAD_LEN;
341347
/*
@@ -344,14 +350,14 @@ u32 vidtv_pes_write_into(struct pes_write_args args)
344350
* the space needed for the TS header _and_ for the PES header
345351
*/
346352
if (!wrote_pes_header)
347-
available_space -= vidtv_pes_h_get_len(args.send_pts,
348-
args.send_dts);
353+
available_space -= vidtv_pes_h_get_len(args->send_pts,
354+
args->send_dts);
349355

350356
/*
351357
* if the encoder has inserted stuffing bytes in the PES
352358
* header, account for them.
353359
*/
354-
available_space -= args.n_pes_h_s_bytes;
360+
available_space -= args->n_pes_h_s_bytes;
355361

356362
/* Take the extra adaptation into account if need to send PCR */
357363
if (need_pcr) {
@@ -386,14 +392,9 @@ u32 vidtv_pes_write_into(struct pes_write_args args)
386392
}
387393

388394
/* write ts header */
389-
ts_header_args.dest_buf = args.dest_buf;
390-
ts_header_args.dest_offset = args.dest_offset + nbytes;
391-
ts_header_args.dest_buf_sz = args.dest_buf_sz;
392-
ts_header_args.pid = args.pid;
393-
ts_header_args.pcr = args.pcr;
394-
ts_header_args.continuity_counter = args.continuity_counter;
395-
ts_header_args.wrote_pes_header = wrote_pes_header;
396-
ts_header_args.n_stuffing_bytes = stuff_bytes;
395+
ts_header_args.dest_offset = args->dest_offset + nbytes;
396+
ts_header_args.wrote_pes_header = wrote_pes_header;
397+
ts_header_args.n_stuffing_bytes = stuff_bytes;
397398

398399
nbytes += vidtv_pes_write_ts_h(ts_header_args, need_pcr,
399400
&last_pcr);
@@ -402,33 +403,20 @@ u32 vidtv_pes_write_into(struct pes_write_args args)
402403

403404
if (!wrote_pes_header) {
404405
/* write the PES header only once */
405-
pes_header_args.dest_buf = args.dest_buf;
406-
407-
pes_header_args.dest_offset = args.dest_offset +
408-
nbytes;
409-
410-
pes_header_args.dest_buf_sz = args.dest_buf_sz;
411-
pes_header_args.encoder_id = args.encoder_id;
412-
pes_header_args.send_pts = args.send_pts;
413-
pes_header_args.pts = args.pts;
414-
pes_header_args.send_dts = args.send_dts;
415-
pes_header_args.dts = args.dts;
416-
pes_header_args.stream_id = args.stream_id;
417-
pes_header_args.n_pes_h_s_bytes = args.n_pes_h_s_bytes;
418-
pes_header_args.access_unit_len = args.access_unit_len;
419-
420-
nbytes += vidtv_pes_write_h(pes_header_args);
421-
wrote_pes_header = true;
406+
pes_header_args.dest_offset = args->dest_offset +
407+
nbytes;
408+
nbytes += vidtv_pes_write_h(&pes_header_args);
409+
wrote_pes_header = true;
422410
}
423411

424412
/* write as much of the payload as we possibly can */
425-
nbytes += vidtv_memcpy(args.dest_buf,
426-
args.dest_offset + nbytes,
427-
args.dest_buf_sz,
428-
args.from,
413+
nbytes += vidtv_memcpy(args->dest_buf,
414+
args->dest_offset + nbytes,
415+
args->dest_buf_sz,
416+
args->from,
429417
payload_size);
430418

431-
args.from += payload_size;
419+
args->from += payload_size;
432420

433421
remaining_len -= payload_size;
434422
}

drivers/media/test-drivers/vidtv/vidtv_pes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,6 @@ struct pes_write_args {
185185
* equal to the size of the access unit, since we need space for PES headers, TS headers
186186
* and padding bytes, if any.
187187
*/
188-
u32 vidtv_pes_write_into(struct pes_write_args args);
188+
u32 vidtv_pes_write_into(struct pes_write_args *args);
189189

190190
#endif // VIDTV_PES_H

0 commit comments

Comments
 (0)