Commit 039b7cae authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

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: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent 91a8a240
...@@ -45,6 +45,7 @@ static void vidtv_channel_encoder_destroy(struct vidtv_encoder *e) ...@@ -45,6 +45,7 @@ static void vidtv_channel_encoder_destroy(struct vidtv_encoder *e)
} }
#define ENCODING_ISO8859_15 "\x0b" #define ENCODING_ISO8859_15 "\x0b"
#define TS_NIT_PID 0x10
/* /*
* init an audio only channel with a s302m encoder * init an audio only channel with a s302m encoder
...@@ -296,6 +297,8 @@ vidtv_channel_pat_prog_cat_into_new(struct vidtv_mux *m) ...@@ -296,6 +297,8 @@ vidtv_channel_pat_prog_cat_into_new(struct vidtv_mux *m)
cur_chnl = cur_chnl->next; cur_chnl = cur_chnl->next;
} }
/* Add the NIT table */
vidtv_psi_pat_program_init(tail, 0, TS_NIT_PID);
return head; return head;
} }
...@@ -471,7 +474,7 @@ int vidtv_channel_si_init(struct vidtv_mux *m) ...@@ -471,7 +474,7 @@ int vidtv_channel_si_init(struct vidtv_mux *m)
vidtv_channel_pmt_match_sections(m->channels, vidtv_channel_pmt_match_sections(m->channels,
m->si.pmt_secs, m->si.pmt_secs,
m->si.pat->programs); m->si.pat->num_pmt);
vidtv_channel_destroy_service_list(service_list); vidtv_channel_destroy_service_list(service_list);
...@@ -498,12 +501,11 @@ int vidtv_channel_si_init(struct vidtv_mux *m) ...@@ -498,12 +501,11 @@ int vidtv_channel_si_init(struct vidtv_mux *m)
void vidtv_channel_si_destroy(struct vidtv_mux *m) void vidtv_channel_si_destroy(struct vidtv_mux *m)
{ {
u16 num_programs = m->si.pat->programs;
u32 i; u32 i;
vidtv_psi_pat_table_destroy(m->si.pat); vidtv_psi_pat_table_destroy(m->si.pat);
for (i = 0; i < num_programs; ++i) for (i = 0; i < m->si.pat->num_pmt; ++i)
vidtv_psi_pmt_table_destroy(m->si.pmt_secs[i]); vidtv_psi_pmt_table_destroy(m->si.pmt_secs[i]);
kfree(m->si.pmt_secs); kfree(m->si.pmt_secs);
......
...@@ -175,7 +175,7 @@ static u32 vidtv_mux_push_si(struct vidtv_mux *m) ...@@ -175,7 +175,7 @@ static u32 vidtv_mux_push_si(struct vidtv_mux *m)
m->mux_buf_offset += vidtv_psi_pat_write_into(pat_args); m->mux_buf_offset += vidtv_psi_pat_write_into(pat_args);
for (i = 0; i < m->si.pat->programs; ++i) { for (i = 0; i < m->si.pat->num_pmt; ++i) {
pmt_pid = vidtv_psi_pmt_get_pid(m->si.pmt_secs[i], pmt_pid = vidtv_psi_pmt_get_pid(m->si.pmt_secs[i],
m->si.pat); m->si.pat);
......
...@@ -794,7 +794,7 @@ vidtv_psi_pat_table_update_sec_len(struct vidtv_psi_table_pat *pat) ...@@ -794,7 +794,7 @@ vidtv_psi_pat_table_update_sec_len(struct vidtv_psi_table_pat *pat)
length += PAT_LEN_UNTIL_LAST_SECTION_NUMBER; length += PAT_LEN_UNTIL_LAST_SECTION_NUMBER;
/* do not count the pointer */ /* do not count the pointer */
for (i = 0; i < pat->programs; ++i) for (i = 0; i < pat->num_pat; ++i)
length += sizeof(struct vidtv_psi_table_pat_program) - length += sizeof(struct vidtv_psi_table_pat_program) -
sizeof(struct vidtv_psi_table_pat_program *); sizeof(struct vidtv_psi_table_pat_program *);
...@@ -931,7 +931,7 @@ vidtv_psi_pat_program_assign(struct vidtv_psi_table_pat *pat, ...@@ -931,7 +931,7 @@ vidtv_psi_pat_program_assign(struct vidtv_psi_table_pat *pat,
program = program->next; program = program->next;
} }
pat->programs = program_count; pat->num_pat = program_count;
pat->program = p; pat->program = p;
/* Recompute section length */ /* Recompute section length */
...@@ -966,8 +966,6 @@ struct vidtv_psi_table_pat *vidtv_psi_pat_table_init(u16 transport_stream_id) ...@@ -966,8 +966,6 @@ struct vidtv_psi_table_pat *vidtv_psi_pat_table_init(u16 transport_stream_id)
pat->header.section_id = 0x0; pat->header.section_id = 0x0;
pat->header.last_section = 0x0; pat->header.last_section = 0x0;
pat->programs = 0;
vidtv_psi_pat_table_update_sec_len(pat); vidtv_psi_pat_table_update_sec_len(pat);
return pat; return pat;
...@@ -1488,22 +1486,43 @@ vidtv_psi_pmt_create_sec_for_each_pat_entry(struct vidtv_psi_table_pat *pat, ...@@ -1488,22 +1486,43 @@ vidtv_psi_pmt_create_sec_for_each_pat_entry(struct vidtv_psi_table_pat *pat,
u16 pcr_pid) u16 pcr_pid)
{ {
struct vidtv_psi_table_pat_program *program = pat->program; struct vidtv_psi_table_pat_program *program;
struct vidtv_psi_table_pmt **pmt_secs; struct vidtv_psi_table_pmt **pmt_secs;
u32 i = 0; u32 i = 0, num_pmt = 0;
/* a section for each program_id */ /*
pmt_secs = kcalloc(pat->programs, * The number of PMT entries is the number of PAT entries
* that contain service_id. That exclude special tables, like NIT
*/
program = pat->program;
while (program) {
if (program->service_id)
num_pmt++;
program = program->next;
}
pmt_secs = kcalloc(num_pmt,
sizeof(struct vidtv_psi_table_pmt *), sizeof(struct vidtv_psi_table_pmt *),
GFP_KERNEL); GFP_KERNEL);
if (!pmt_secs) if (!pmt_secs)
return NULL; return NULL;
while (program) { for (program = pat->program; program; program = program->next) {
pmt_secs[i] = vidtv_psi_pmt_table_init(be16_to_cpu(program->service_id), pcr_pid); if (!program->service_id)
++i; continue;
program = program->next; pmt_secs[i] = vidtv_psi_pmt_table_init(be16_to_cpu(program->service_id),
pcr_pid);
if (!pmt_secs[i]) {
while (i > 0) {
i--;
vidtv_psi_pmt_table_destroy(pmt_secs[i]);
}
return NULL;
}
i++;
} }
pat->num_pmt = num_pmt;
return pmt_secs; return pmt_secs;
} }
......
...@@ -174,7 +174,8 @@ struct vidtv_psi_table_pat_program { ...@@ -174,7 +174,8 @@ struct vidtv_psi_table_pat_program {
*/ */
struct vidtv_psi_table_pat { struct vidtv_psi_table_pat {
struct vidtv_psi_table_header header; struct vidtv_psi_table_header header;
u16 programs; /* Included by libdvbv5, not part of the table and not actually serialized */ u16 num_pat;
u16 num_pmt;
struct vidtv_psi_table_pat_program *program; struct vidtv_psi_table_pat_program *program;
} __packed; } __packed;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment