libdvbv5: Add support for additional descriptors at VCT table
authorMauro Carvalho Chehab <m.chehab@samsung.com>
Wed, 13 Nov 2013 23:33:07 +0000 (21:33 -0200)
committerMauro Carvalho Chehab <m.chehab@samsung.com>
Wed, 13 Nov 2013 23:42:39 +0000 (21:42 -0200)
Document A/65:2009 allows extra descriptors at the Virtual
Channel Table.

While I don't have it on my test streams, it is better to
add support for it.

Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
lib/include/descriptors/vct.h
lib/libdvbv5/descriptors/vct.c

index 94d783c..b42285d 100644 (file)
@@ -88,9 +88,23 @@ struct dvb_table_vct {
        uint8_t ATSC_protocol_version;
        uint8_t num_channels_in_section;
 
+       /*
+        * Everything after descriptor (including it) won't be bit-mapped
+        * to the data parsed from the MPEG TS. So, metadata are added there
+        */
        struct dvb_table_vct_channel *channel;
+       struct dvb_desc *descriptor;
 } __attribute__((packed));
 
+
+union dvb_table_vct_descriptor_length {
+       uint16_t bitfield;
+       struct {
+               uint16_t descriptor_length:10;
+               uint16_t reserved:6;
+       };
+};
+
 #define dvb_vct_channel_foreach(_service, _vct) \
        for( struct dvb_table_vct_channel *_channel = _vct->channel; _channel; _channel = _channel->next ) \
 
index 70ccd7e..7af3051 100644 (file)
@@ -29,19 +29,21 @@ void dvb_table_vct_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf, ssize
        struct dvb_table_vct_channel **head;
        int i, n;
 
-       if (*table_length >= offsetof(struct dvb_table_vct, channel)) {
+       if (*table_length > 0) {
                /* find end of curent list */
                head = &vct->channel;
                while (*head != NULL)
                        head = &(*head)->next;
        } else {
                memcpy(vct, p, offsetof(struct dvb_table_vct, channel));
-               *table_length = offsetof(struct dvb_table_vct, channel);
+
+               *table_length = sizeof(struct dvb_table_vct);
 
                vct->channel = NULL;
+               vct->descriptor = NULL;
                head = &vct->channel;
        }
-       p += sizeof(struct dvb_table_vct) - sizeof(vct->channel);
+       p += offsetof(struct dvb_table_vct, channel);
 
        struct dvb_table_vct_channel *last = NULL;
        for (n = 0; n < vct->num_channels_in_section; n++) {
@@ -88,6 +90,14 @@ void dvb_table_vct_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf, ssize
                p += channel->descriptors_length;
                last = channel;
        }
+
+       /* Get extra descriptors */
+       if (p < buf + buflen) {
+               union dvb_table_vct_descriptor_length *d = (void *)p;
+               bswap16(d->descriptor_length);
+               p += sizeof(union dvb_table_vct_descriptor_length);
+               dvb_parse_descriptors(parms, p, d->descriptor_length, &vct->descriptor);
+       }
 }
 
 void dvb_table_vct_free(struct dvb_table_vct *vct)
@@ -99,6 +109,8 @@ void dvb_table_vct_free(struct dvb_table_vct *vct)
                channel = channel->next;
                free(tmp);
        }
+       dvb_free_descriptors((struct dvb_desc **) &vct->descriptor);
+
        free(vct);
 }