dvb: add proper support for AC-3 audio
authorMauro Carvalho Chehab <mchehab@redhat.com>
Sat, 14 Jan 2012 11:59:06 +0000 (09:59 -0200)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Sat, 14 Jan 2012 11:59:06 +0000 (09:59 -0200)
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
utils/dvb/descriptors.c
utils/dvb/descriptors.h
utils/dvb/libscan.c

index 24f6e8a..7a83c3f 100644 (file)
@@ -621,11 +621,6 @@ void parse_descriptor(enum dvb_tables type,
        if (len == 0)
                return;
 
-       /*
-        * FIXME: syntax need to be changed, to avoid parsing an invalid
-        * descriptor here (e. g. a descriptor at the wrong table)
-        */
-
        if (dvb_desc->verbose)
                printf("Descriptors table len %d\n", len);
        do {
@@ -637,8 +632,6 @@ void parse_descriptor(enum dvb_tables type,
                                dlen, len);
                        return;
                }
-               /* FIXME: Not all descriptors are valid for all tables */
-
                if (dvb_desc->verbose) {
                        printf("%s (0x%02x), len %d",
                               descriptors[buf[0]], buf[0], buf[1]);
@@ -783,6 +776,26 @@ void parse_descriptor(enum dvb_tables type,
        } while (len > 0);
 }
 
+int has_descriptor(struct dvb_descriptors *dvb_desc,
+                   unsigned char needed_descriptor,
+                   const unsigned char *buf, int len)
+{
+       if (len == 0)
+               return 0;
+
+       do {
+               int dlen = buf[1];
+
+               if (buf[0] == needed_descriptor)
+                       return 1;
+
+               buf += dlen + 2;
+               len -= dlen + 2;
+       } while (len > 0);
+
+       return 0;
+}
+
 #if 0
        /* TODO: remove those stuff */
 
index f33da35..4d557ff 100644 (file)
@@ -160,3 +160,7 @@ enum extension_descriptors {
 void parse_descriptor(enum dvb_tables type,
                      struct dvb_descriptors *dvb_desc,
                      const unsigned char *buf, int len);
+
+int has_descriptor(struct dvb_descriptors *dvb_desc,
+                   unsigned char needed_descriptor,
+                   const unsigned char *buf, int len);
index 21ec99f..cc0d8ca 100644 (file)
@@ -56,6 +56,31 @@ static void parse_pat(struct dvb_descriptors *dvb_desc,
        dvb_desc->pat_table.pid_table_len = n;
 }
 
+static void add_vpid(struct pid_table *pid_table, uint16_t pid, int verbose)
+{
+       int i;
+
+       if (verbose)
+               printf("video pid 0x%04x\n", pid);
+       i = pid_table->video_pid_len;
+       pid_table->video_pid = realloc(pid_table->video_pid,
+               sizeof(*pid_table->video_pid) * ++pid_table->video_pid_len);
+       pid_table->video_pid[i] = pid;
+}
+
+static void add_apid(struct pid_table *pid_table, uint16_t pid, int verbose)
+{
+       int i;
+
+       if (verbose)
+               printf("audio pid 0x%04x\n", pid);
+       i = pid_table->audio_pid_len;
+       pid_table->audio_pid = realloc(pid_table->audio_pid,
+               sizeof(*pid_table->audio_pid) * ++pid_table->audio_pid_len);
+       pid_table->audio_pid[i] = pid;
+}
+
+
 static void parse_pmt(struct dvb_descriptors *dvb_desc,
                      const unsigned char *buf, int *section_length,
                      int id, int version,
@@ -86,31 +111,30 @@ static void parse_pmt(struct dvb_descriptors *dvb_desc,
                pid = ((buf[1] & 0x1f) << 8) | buf[2];
 
                switch (buf[0]) {
-               case 0x01:
-               case 0x02:
-               case 0x10:
-               case 0x1b:
-                       if (dvb_desc->verbose)
-                               printf("video pid 0x%04x\n", pid);
-                       i = pid_table->video_pid_len;
-                       pid_table->video_pid = realloc(pid_table->video_pid,
-                               sizeof(*pid_table->video_pid) *
-                               ++pid_table->video_pid_len);
-                       pid_table->video_pid[i] = pid;
+               case 0x01: /* ISO/IEC 11172-2 Video */
+               case 0x02: /* H.262, ISO/IEC 13818-2 or ISO/IEC 11172-2 video */
+                       add_vpid(pid_table, pid, dvb_desc->verbose);
                        break;
-               case 0x03:
-               case 0x04:
-               case 0x0f:
-               case 0x11:
-               case 0x81:
-                       if (dvb_desc->verbose)
-                               printf("audio pid 0x%04x\n", pid);
-                       i = pid_table->audio_pid_len;
-                       pid_table->audio_pid = realloc(pid_table->audio_pid,
-                               sizeof(*pid_table->audio_pid) *
-                               ++pid_table->audio_pid_len);
-                       pid_table->audio_pid[i] = pid;
-                       /* Discard audio language descriptors */
+               case 0x1b: /* H.264 AVC */
+                       add_vpid(pid_table, pid, dvb_desc->verbose);
+                       break;
+               case 0x03: /* ISO/IEC 11172-3 Audio */
+               case 0x04: /* ISO/IEC 13818-3 Audio */
+               case 0x0f: /* ISO/IEC 13818-7 Audio with ADTS (AAC) */
+               case 0x11: /* ISO/IEC 14496-3 Audio with the LATM */
+               case 0x81: /* user private - in general ATSC Dolby - AC-3 */
+                       add_apid(pid_table, pid, dvb_desc->verbose);
+                       break;
+               case 0x05: /* private sections */
+               case 0x06: /* private data */
+                       /*
+                        * Those can be used by sub-titling, teletext and/or
+                        * DVB AC-3. So, need to seek for the AC-3 descriptors
+                        */
+                       if (has_descriptor(dvb_desc, AC_3_descriptor, &buf[5], len) |
+                           has_descriptor(dvb_desc, enhanced_AC_3_descriptor, &buf[5], len))
+                               add_apid(pid_table, pid, dvb_desc->verbose);
+
                        break;
                default:
                        if (dvb_desc->verbose)