Skip to content

Commit 039b7ca

Browse files
committed
media: vidtv: add a PID entry for the NIT table
On normal TS streams, the NIT table has its own entry at PAT, but not at PMT. While here, properly handle alloc problems when creating PMT entries. Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
1 parent 91a8a24 commit 039b7ca

4 files changed

Lines changed: 39 additions & 17 deletions

File tree

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ static void vidtv_channel_encoder_destroy(struct vidtv_encoder *e)
4545
}
4646

4747
#define ENCODING_ISO8859_15 "\x0b"
48+
#define TS_NIT_PID 0x10
4849

4950
/*
5051
* init an audio only channel with a s302m encoder
@@ -296,6 +297,8 @@ vidtv_channel_pat_prog_cat_into_new(struct vidtv_mux *m)
296297

297298
cur_chnl = cur_chnl->next;
298299
}
300+
/* Add the NIT table */
301+
vidtv_psi_pat_program_init(tail, 0, TS_NIT_PID);
299302

300303
return head;
301304
}
@@ -471,7 +474,7 @@ int vidtv_channel_si_init(struct vidtv_mux *m)
471474

472475
vidtv_channel_pmt_match_sections(m->channels,
473476
m->si.pmt_secs,
474-
m->si.pat->programs);
477+
m->si.pat->num_pmt);
475478

476479
vidtv_channel_destroy_service_list(service_list);
477480

@@ -498,12 +501,11 @@ int vidtv_channel_si_init(struct vidtv_mux *m)
498501

499502
void vidtv_channel_si_destroy(struct vidtv_mux *m)
500503
{
501-
u16 num_programs = m->si.pat->programs;
502504
u32 i;
503505

504506
vidtv_psi_pat_table_destroy(m->si.pat);
505507

506-
for (i = 0; i < num_programs; ++i)
508+
for (i = 0; i < m->si.pat->num_pmt; ++i)
507509
vidtv_psi_pmt_table_destroy(m->si.pmt_secs[i]);
508510

509511
kfree(m->si.pmt_secs);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ static u32 vidtv_mux_push_si(struct vidtv_mux *m)
175175

176176
m->mux_buf_offset += vidtv_psi_pat_write_into(pat_args);
177177

178-
for (i = 0; i < m->si.pat->programs; ++i) {
178+
for (i = 0; i < m->si.pat->num_pmt; ++i) {
179179
pmt_pid = vidtv_psi_pmt_get_pid(m->si.pmt_secs[i],
180180
m->si.pat);
181181

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

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,7 @@ vidtv_psi_pat_table_update_sec_len(struct vidtv_psi_table_pat *pat)
794794
length += PAT_LEN_UNTIL_LAST_SECTION_NUMBER;
795795

796796
/* do not count the pointer */
797-
for (i = 0; i < pat->programs; ++i)
797+
for (i = 0; i < pat->num_pat; ++i)
798798
length += sizeof(struct vidtv_psi_table_pat_program) -
799799
sizeof(struct vidtv_psi_table_pat_program *);
800800

@@ -931,7 +931,7 @@ vidtv_psi_pat_program_assign(struct vidtv_psi_table_pat *pat,
931931
program = program->next;
932932
}
933933

934-
pat->programs = program_count;
934+
pat->num_pat = program_count;
935935
pat->program = p;
936936

937937
/* Recompute section length */
@@ -966,8 +966,6 @@ struct vidtv_psi_table_pat *vidtv_psi_pat_table_init(u16 transport_stream_id)
966966
pat->header.section_id = 0x0;
967967
pat->header.last_section = 0x0;
968968

969-
pat->programs = 0;
970-
971969
vidtv_psi_pat_table_update_sec_len(pat);
972970

973971
return pat;
@@ -1488,22 +1486,43 @@ vidtv_psi_pmt_create_sec_for_each_pat_entry(struct vidtv_psi_table_pat *pat,
14881486
u16 pcr_pid)
14891487

14901488
{
1491-
struct vidtv_psi_table_pat_program *program = pat->program;
1489+
struct vidtv_psi_table_pat_program *program;
14921490
struct vidtv_psi_table_pmt **pmt_secs;
1493-
u32 i = 0;
1491+
u32 i = 0, num_pmt = 0;
14941492

1495-
/* a section for each program_id */
1496-
pmt_secs = kcalloc(pat->programs,
1493+
/*
1494+
* The number of PMT entries is the number of PAT entries
1495+
* that contain service_id. That exclude special tables, like NIT
1496+
*/
1497+
program = pat->program;
1498+
while (program) {
1499+
if (program->service_id)
1500+
num_pmt++;
1501+
program = program->next;
1502+
}
1503+
1504+
pmt_secs = kcalloc(num_pmt,
14971505
sizeof(struct vidtv_psi_table_pmt *),
14981506
GFP_KERNEL);
14991507
if (!pmt_secs)
15001508
return NULL;
15011509

1502-
while (program) {
1503-
pmt_secs[i] = vidtv_psi_pmt_table_init(be16_to_cpu(program->service_id), pcr_pid);
1504-
++i;
1505-
program = program->next;
1510+
for (program = pat->program; program; program = program->next) {
1511+
if (!program->service_id)
1512+
continue;
1513+
pmt_secs[i] = vidtv_psi_pmt_table_init(be16_to_cpu(program->service_id),
1514+
pcr_pid);
1515+
1516+
if (!pmt_secs[i]) {
1517+
while (i > 0) {
1518+
i--;
1519+
vidtv_psi_pmt_table_destroy(pmt_secs[i]);
1520+
}
1521+
return NULL;
1522+
}
1523+
i++;
15061524
}
1525+
pat->num_pmt = num_pmt;
15071526

15081527
return pmt_secs;
15091528
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,8 @@ struct vidtv_psi_table_pat_program {
174174
*/
175175
struct vidtv_psi_table_pat {
176176
struct vidtv_psi_table_header header;
177-
u16 programs; /* Included by libdvbv5, not part of the table and not actually serialized */
177+
u16 num_pat;
178+
u16 num_pmt;
178179
struct vidtv_psi_table_pat_program *program;
179180
} __packed;
180181

0 commit comments

Comments
 (0)