]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
media: vidtv: add a PID entry for the NIT table
authorMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Mon, 23 Nov 2020 13:16:40 +0000 (14:16 +0100)
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Thu, 26 Nov 2020 07:05:23 +0000 (08:05 +0100)
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>
drivers/media/test-drivers/vidtv/vidtv_channel.c
drivers/media/test-drivers/vidtv/vidtv_mux.c
drivers/media/test-drivers/vidtv/vidtv_psi.c
drivers/media/test-drivers/vidtv/vidtv_psi.h

index 77e33f33afee12f8e7a41b24e7f98db111ae9b5c..c3261494120e48e23e5a3b725719016b8d3026ac 100644 (file)
@@ -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;
 }
@@ -471,7 +474,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);
 
@@ -498,12 +501,11 @@ free_pat:
 
 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);
index e0cc74e98632fe37a06d01225a3a8e67a9787042..0cf784c09024768e98457a2775feb6bad0f1cf99 100644 (file)
@@ -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);
 
index 02dd217bdbf659590c2eafb8ddf2ee529cc63b84..5c887639b676e98d1d425c09b50d43a1533732a6 100644 (file)
@@ -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;
 }
index d8645d75c3f14307d8bd7be3d84d68437ec4b33e..c3bd440e13205371bd1262c684588e22f68ef7d6 100644 (file)
@@ -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;