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+hua...@kernel.org>
---
 .../media/test-drivers/vidtv/vidtv_channel.c  |  8 ++--
 drivers/media/test-drivers/vidtv/vidtv_mux.c  |  2 +-
 drivers/media/test-drivers/vidtv/vidtv_psi.c  | 43 +++++++++++++------
 drivers/media/test-drivers/vidtv/vidtv_psi.h  |  3 +-
 4 files changed, 39 insertions(+), 17 deletions(-)

diff --git a/drivers/media/test-drivers/vidtv/vidtv_channel.c 
b/drivers/media/test-drivers/vidtv/vidtv_channel.c
index d1d312566bc0..b7cf8caaeb40 100644
--- a/drivers/media/test-drivers/vidtv/vidtv_channel.c
+++ b/drivers/media/test-drivers/vidtv/vidtv_channel.c
@@ -45,6 +45,7 @@ static void vidtv_channel_encoder_destroy(struct 
vidtv_encoder *e)
 }
 
 #define ENCODING_ISO8859_15 "\x0b"
+#define TS_NIT_PID     0x10
 
 /*
  * init an audio only channel with a s302m encoder
@@ -296,6 +297,8 @@ vidtv_channel_pat_prog_cat_into_new(struct vidtv_mux *m)
 
                cur_chnl = cur_chnl->next;
        }
+       /* Add the NIT table */
+       vidtv_psi_pat_program_init(tail, 0, TS_NIT_PID);
 
        return head;
 }
@@ -473,7 +476,7 @@ int vidtv_channel_si_init(struct vidtv_mux *m)
 
        vidtv_channel_pmt_match_sections(m->channels,
                                         m->si.pmt_secs,
-                                        m->si.pat->programs);
+                                        m->si.pat->num_pmt);
 
        vidtv_channel_destroy_service_list(service_list);
 
@@ -500,12 +503,11 @@ int vidtv_channel_si_init(struct vidtv_mux *m)
 
 void vidtv_channel_si_destroy(struct vidtv_mux *m)
 {
-       u16 num_programs = m->si.pat->programs;
        u32 i;
 
        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]);
 
        kfree(m->si.pmt_secs);
diff --git a/drivers/media/test-drivers/vidtv/vidtv_mux.c 
b/drivers/media/test-drivers/vidtv/vidtv_mux.c
index e0cc74e98632..0cf784c09024 100644
--- a/drivers/media/test-drivers/vidtv/vidtv_mux.c
+++ b/drivers/media/test-drivers/vidtv/vidtv_mux.c
@@ -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);
 
-       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],
                                                m->si.pat);
 
diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c 
b/drivers/media/test-drivers/vidtv/vidtv_psi.c
index 02dd217bdbf6..5c887639b676 100644
--- a/drivers/media/test-drivers/vidtv/vidtv_psi.c
+++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c
@@ -794,7 +794,7 @@ vidtv_psi_pat_table_update_sec_len(struct 
vidtv_psi_table_pat *pat)
        length += PAT_LEN_UNTIL_LAST_SECTION_NUMBER;
 
        /* 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) -
                          sizeof(struct vidtv_psi_table_pat_program *);
 
@@ -931,7 +931,7 @@ vidtv_psi_pat_program_assign(struct vidtv_psi_table_pat 
*pat,
                        program = program->next;
                }
 
-               pat->programs = program_count;
+               pat->num_pat = program_count;
                pat->program  = p;
 
                /* Recompute section length */
@@ -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.last_section = 0x0;
 
-       pat->programs = 0;
-
        vidtv_psi_pat_table_update_sec_len(pat);
 
        return pat;
@@ -1488,22 +1486,43 @@ vidtv_psi_pmt_create_sec_for_each_pat_entry(struct 
vidtv_psi_table_pat *pat,
                                            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;
-       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 *),
                           GFP_KERNEL);
        if (!pmt_secs)
                return NULL;
 
-       while (program) {
-               pmt_secs[i] = 
vidtv_psi_pmt_table_init(be16_to_cpu(program->service_id), pcr_pid);
-               ++i;
-               program = program->next;
+       for (program = pat->program; program; program = program->next) {
+               if (!program->service_id)
+                       continue;
+               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;
 }
diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.h 
b/drivers/media/test-drivers/vidtv/vidtv_psi.h
index 26b2c2f5774c..8f98bcaf6229 100644
--- a/drivers/media/test-drivers/vidtv/vidtv_psi.h
+++ b/drivers/media/test-drivers/vidtv/vidtv_psi.h
@@ -174,7 +174,8 @@ struct vidtv_psi_table_pat_program {
  */
 struct vidtv_psi_table_pat {
        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;
 } __packed;
 
-- 
2.28.0

Reply via email to