From dd6dbe8d7e312238cc0ad0b907042a96b0505d44 Mon Sep 17 00:00:00 2001 From: "Daniel W. S. Almeida" Date: Sat, 31 Oct 2020 16:05:47 +0100 Subject: media: vidtv: extract the initial CRC value to into a #define The same constant (0xffffffff) is used in three different functions. Extract it into a #define to avoid repetition. Signed-off-by: Daniel W. S. Almeida Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_psi.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c index 82cf67dd27c0..f2e25e68c085 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.c +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c @@ -31,6 +31,7 @@ #define CRC_SIZE_IN_BYTES 4 #define MAX_VERSION_NUM 32 +#define INITIAL_CRC 0xffffffff static const u32 CRC_LUT[256] = { /* from libdvbv5 */ @@ -784,7 +785,7 @@ u32 vidtv_psi_pat_write_into(struct vidtv_psi_pat_write_args args) /* the number of bytes written by this function */ u32 nbytes = 0; const u16 pat_pid = VIDTV_PAT_PID; - u32 crc = 0xffffffff; + u32 crc = INITIAL_CRC; struct vidtv_psi_table_pat_program *p = args.pat->program; @@ -974,7 +975,7 @@ u32 vidtv_psi_pmt_write_into(struct vidtv_psi_pmt_write_args args) { /* the number of bytes written by this function */ u32 nbytes = 0; - u32 crc = 0xffffffff; + u32 crc = INITIAL_CRC; struct vidtv_psi_desc *table_descriptor = args.pmt->descriptor; struct vidtv_psi_table_pmt_stream *stream = args.pmt->stream; @@ -1124,7 +1125,7 @@ u32 vidtv_psi_sdt_write_into(struct vidtv_psi_sdt_write_args args) u32 nbytes = 0; u16 sdt_pid = VIDTV_SDT_PID; /* see ETSI EN 300 468 v1.15.1 p. 11 */ - u32 crc = 0xffffffff; + u32 crc = INITIAL_CRC; struct vidtv_psi_table_sdt_service *service = args.sdt->service; struct vidtv_psi_desc *service_desc = (args.sdt->service) ? -- cgit v1.2.3 From c2f78f0cb294aa6f009d3a170f4ee8ad199ba5da Mon Sep 17 00:00:00 2001 From: "Daniel W. S. Almeida" Date: Sat, 31 Oct 2020 16:05:48 +0100 Subject: media: vidtv: psi: add a Network Information Table (NIT) Add a Network Information Table (NIT) as specified in ETSI EN 300 468. This table conveys information relating to the physical organization of the multiplexes carried via a given network and the characteristics of the network itself. It is conveyed in the output of vidtv as packets with TS PID of 0x0010 [mchehab+huawei@kernel.org: removed an extra blank line] Signed-off-by: Daniel W. S. Almeida Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- Documentation/driver-api/media/drivers/vidtv.rst | 6 +- drivers/media/test-drivers/vidtv/vidtv_bridge.c | 4 + drivers/media/test-drivers/vidtv/vidtv_channel.c | 59 ++++ drivers/media/test-drivers/vidtv/vidtv_mux.c | 16 ++ drivers/media/test-drivers/vidtv/vidtv_mux.h | 9 + drivers/media/test-drivers/vidtv/vidtv_psi.c | 345 ++++++++++++++++++++++- drivers/media/test-drivers/vidtv/vidtv_psi.h | 118 +++++++- 7 files changed, 545 insertions(+), 12 deletions(-) diff --git a/Documentation/driver-api/media/drivers/vidtv.rst b/Documentation/driver-api/media/drivers/vidtv.rst index 65115448c52d..2d7ddf676b13 100644 --- a/Documentation/driver-api/media/drivers/vidtv.rst +++ b/Documentation/driver-api/media/drivers/vidtv.rst @@ -149,11 +149,11 @@ vidtv_psi.[ch] Because the generator is implemented in a separate file, it can be reused elsewhere in the media subsystem. - Currently vidtv supports working with 3 PSI tables: PAT, PMT and - SDT. + Currently vidtv supports working with 4 PSI tables: PAT, PMT, + SDT and NIT. The specification for PAT and PMT can be found in *ISO 13818-1: - Systems*, while the specification for the SDT can be found in *ETSI + Systems*, while the specification for the SDT, NIT can be found in *ETSI EN 300 468: Specification for Service Information (SI) in DVB systems*. diff --git a/drivers/media/test-drivers/vidtv/vidtv_bridge.c b/drivers/media/test-drivers/vidtv/vidtv_bridge.c index 74b054947bbe..2f97ecf423ed 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_bridge.c +++ b/drivers/media/test-drivers/vidtv/vidtv_bridge.c @@ -28,6 +28,8 @@ //#define MUX_BUF_MIN_SZ #define TUNER_DEFAULT_ADDR 0x68 #define DEMOD_DEFAULT_ADDR 0x60 +#define VIDTV_DEFAULT_NETWORK_ID 0x744 +#define VIDTV_DEFAULT_NETWORK_NAME "LinuxTV.org" /* LNBf fake parameters: ranges used by an Universal (extended) European LNBf */ #define LNB_CUT_FREQUENCY 11700000 @@ -177,6 +179,8 @@ static int vidtv_start_streaming(struct vidtv_dvb *dvb) mux_args.si_period_usecs = si_period_msec * 1000; mux_args.pcr_pid = pcr_pid; mux_args.transport_stream_id = VIDTV_DEFAULT_TS_ID; + mux_args.network_id = VIDTV_DEFAULT_NETWORK_ID, + mux_args.network_name = VIDTV_DEFAULT_NETWORK_NAME, mux_args.priv = dvb; dvb->streaming = true; diff --git a/drivers/media/test-drivers/vidtv/vidtv_channel.c b/drivers/media/test-drivers/vidtv/vidtv_channel.c index f2b97cf08e87..a246b49123d9 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_channel.c +++ b/drivers/media/test-drivers/vidtv/vidtv_channel.c @@ -246,10 +246,57 @@ vidtv_channel_pmt_match_sections(struct vidtv_channel *channels, } } +static struct vidtv_psi_desc_service_list_entry +*vidtv_channel_build_service_list(struct vidtv_psi_table_sdt_service *s) +{ + struct vidtv_psi_desc_service_list_entry *curr_e = NULL; + struct vidtv_psi_desc_service_list_entry *head_e = NULL; + struct vidtv_psi_desc_service_list_entry *prev_e = NULL; + struct vidtv_psi_desc *desc = s->descriptor; + struct vidtv_psi_desc_service *s_desc; + + while (s) { + while (desc) { + if (s->descriptor->type != SERVICE_DESCRIPTOR) + goto next_desc; + + s_desc = (struct vidtv_psi_desc_service *)desc; + + curr_e = kzalloc(sizeof(*curr_e), GFP_KERNEL); + curr_e->service_id = s->service_id; + curr_e->service_type = s_desc->service_type; + + if (!head_e) + head_e = curr_e; + if (prev_e) + prev_e->next = curr_e; + + prev_e = curr_e; + +next_desc: + desc = desc->next; + } + s = s->next; + } + return head_e; +} + +static void vidtv_channel_destroy_service_list(struct vidtv_psi_desc_service_list_entry *e) +{ + struct vidtv_psi_desc_service_list_entry *tmp; + + while (e) { + tmp = e; + e = e->next; + kfree(tmp); + } +} + void vidtv_channel_si_init(struct vidtv_mux *m) { struct vidtv_psi_table_pat_program *programs = NULL; struct vidtv_psi_table_sdt_service *services = NULL; + struct vidtv_psi_desc_service_list_entry *service_list = NULL; m->si.pat = vidtv_psi_pat_table_init(m->transport_stream_id); @@ -258,6 +305,15 @@ void vidtv_channel_si_init(struct vidtv_mux *m) programs = vidtv_channel_pat_prog_cat_into_new(m); services = vidtv_channel_sdt_serv_cat_into_new(m); + /* look for a service descriptor for every service */ + service_list = vidtv_channel_build_service_list(services); + + /* use these descriptors to build the NIT */ + m->si.nit = vidtv_psi_nit_table_init(m->network_id, + m->transport_stream_id, + m->network_name, + service_list); + /* assemble all programs and assign to PAT */ vidtv_psi_pat_program_assign(m->si.pat, programs); @@ -269,6 +325,8 @@ void vidtv_channel_si_init(struct vidtv_mux *m) vidtv_channel_pmt_match_sections(m->channels, m->si.pmt_secs, m->si.pat->programs); + + vidtv_channel_destroy_service_list(service_list); } void vidtv_channel_si_destroy(struct vidtv_mux *m) @@ -283,6 +341,7 @@ void vidtv_channel_si_destroy(struct vidtv_mux *m) kfree(m->si.pmt_secs); vidtv_psi_sdt_table_destroy(m->si.sdt); + vidtv_psi_nit_table_destroy(m->si.nit); } void vidtv_channels_init(struct vidtv_mux *m) diff --git a/drivers/media/test-drivers/vidtv/vidtv_mux.c b/drivers/media/test-drivers/vidtv/vidtv_mux.c index 082740ae9d44..2a960e87c39c 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_mux.c +++ b/drivers/media/test-drivers/vidtv/vidtv_mux.c @@ -74,6 +74,8 @@ static void vidtv_mux_pid_ctx_init(struct vidtv_mux *m) vidtv_mux_create_pid_ctx_once(m, VIDTV_PAT_PID); /* push the SDT pid ctx */ vidtv_mux_create_pid_ctx_once(m, VIDTV_SDT_PID); + /* push the NIT pid ctx */ + vidtv_mux_create_pid_ctx_once(m, VIDTV_NIT_PID); /* add a ctx for all PMT sections */ while (p) { @@ -117,10 +119,12 @@ static u32 vidtv_mux_push_si(struct vidtv_mux *m) struct vidtv_mux_pid_ctx *pat_ctx; struct vidtv_mux_pid_ctx *pmt_ctx; struct vidtv_mux_pid_ctx *sdt_ctx; + struct vidtv_mux_pid_ctx *nit_ctx; struct vidtv_psi_pat_write_args pat_args = {}; struct vidtv_psi_pmt_write_args pmt_args = {}; struct vidtv_psi_sdt_write_args sdt_args = {}; + struct vidtv_psi_nit_write_args nit_args = {}; u32 nbytes; /* the number of bytes written by this function */ u16 pmt_pid; @@ -128,6 +132,7 @@ static u32 vidtv_mux_push_si(struct vidtv_mux *m) pat_ctx = vidtv_mux_get_pid_ctx(m, VIDTV_PAT_PID); sdt_ctx = vidtv_mux_get_pid_ctx(m, VIDTV_SDT_PID); + nit_ctx = vidtv_mux_get_pid_ctx(m, VIDTV_NIT_PID); pat_args.buf = m->mux_buf; pat_args.offset = m->mux_buf_offset; @@ -169,6 +174,14 @@ static u32 vidtv_mux_push_si(struct vidtv_mux *m) m->mux_buf_offset += vidtv_psi_sdt_write_into(sdt_args); + nit_args.buf = m->mux_buf; + nit_args.offset = m->mux_buf_offset; + nit_args.nit = m->si.nit; + nit_args.buf_sz = m->mux_buf_sz; + nit_args.continuity_counter = &nit_ctx->cc; + + m->mux_buf_offset += vidtv_psi_nit_write_into(nit_args); + nbytes = m->mux_buf_offset - initial_offset; m->num_streamed_si++; @@ -446,6 +459,8 @@ struct vidtv_mux *vidtv_mux_init(struct dvb_frontend *fe, m->pcr_pid = args.pcr_pid; m->transport_stream_id = args.transport_stream_id; m->priv = args.priv; + m->network_id = args.network_id; + m->network_name = kstrdup(args.network_name, GFP_KERNEL); m->timing.current_jiffies = get_jiffies_64(); if (args.channels) @@ -469,6 +484,7 @@ void vidtv_mux_destroy(struct vidtv_mux *m) vidtv_mux_pid_ctx_destroy(m); vidtv_channel_si_destroy(m); vidtv_channels_destroy(m); + kfree(m->network_name); vfree(m->mux_buf); kfree(m); } diff --git a/drivers/media/test-drivers/vidtv/vidtv_mux.h b/drivers/media/test-drivers/vidtv/vidtv_mux.h index 2caa60623e97..5dfbe30c2ac8 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_mux.h +++ b/drivers/media/test-drivers/vidtv/vidtv_mux.h @@ -64,6 +64,7 @@ struct vidtv_mux_si { struct vidtv_psi_table_pat *pat; struct vidtv_psi_table_pmt **pmt_secs; /* the PMT sections */ struct vidtv_psi_table_sdt *sdt; + struct vidtv_psi_table_nit *nit; }; /** @@ -99,6 +100,8 @@ struct vidtv_mux_pid_ctx { * @pcr_pid: The TS PID used for the PSI packets. All channels will share the * same PCR. * @transport_stream_id: The transport stream ID + * @network_id: The network ID + * @network_name: The network name * @priv: Private data. */ struct vidtv_mux { @@ -128,6 +131,8 @@ struct vidtv_mux { u16 pcr_pid; u16 transport_stream_id; + u16 network_id; + char *network_name; void *priv; }; @@ -142,6 +147,8 @@ struct vidtv_mux { * same PCR. * @transport_stream_id: The transport stream ID * @channels: an optional list of channels to use + * @network_id: The network ID + * @network_name: The network name * @priv: Private data. */ struct vidtv_mux_init_args { @@ -153,6 +160,8 @@ struct vidtv_mux_init_args { u16 pcr_pid; u16 transport_stream_id; struct vidtv_channel *channels; + u16 network_id; + char *network_name; void *priv; }; diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c index f2e25e68c085..0de6d646a483 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.c +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c @@ -6,10 +6,6 @@ * technically be broken into one or more sections, we do not do this here, * hence 'table' and 'section' are interchangeable for vidtv. * - * This code currently supports three tables: PAT, PMT and SDT. These are the - * bare minimum to get userspace to recognize our MPEG transport stream. It can - * be extended to support more PSI tables in the future. - * * Copyright (C) 2020 Daniel W. S. Almeida */ @@ -389,6 +385,75 @@ struct vidtv_psi_desc_registration return desc; } +struct vidtv_psi_desc_network_name +*vidtv_psi_network_name_desc_init(struct vidtv_psi_desc *head, char *network_name) +{ + struct vidtv_psi_desc_network_name *desc; + u32 network_name_len = network_name ? strlen(network_name) : 0; + + desc = kzalloc(sizeof(*desc), GFP_KERNEL); + + desc->type = NETWORK_NAME_DESCRIPTOR; + + desc->length = network_name_len; + + if (network_name && network_name_len) + desc->network_name = kstrdup(network_name, GFP_KERNEL); + + if (head) { + while (head->next) + head = head->next; + + head->next = (struct vidtv_psi_desc *)desc; + } + + return desc; +} + +struct vidtv_psi_desc_service_list +*vidtv_psi_service_list_desc_init(struct vidtv_psi_desc *head, + struct vidtv_psi_desc_service_list_entry *entry) +{ + struct vidtv_psi_desc_service_list *desc; + struct vidtv_psi_desc_service_list_entry *curr_e = NULL; + struct vidtv_psi_desc_service_list_entry *head_e = NULL; + struct vidtv_psi_desc_service_list_entry *prev_e = NULL; + u16 length = 0; + + desc = kzalloc(sizeof(*desc), GFP_KERNEL); + + desc->type = SERVICE_LIST_DESCRIPTOR; + + while (entry) { + curr_e = kzalloc(sizeof(*curr_e), GFP_KERNEL); + curr_e->service_id = entry->service_id; + curr_e->service_type = entry->service_type; + + length += sizeof(struct vidtv_psi_desc_service_list_entry) - + sizeof(struct vidtv_psi_desc_service_list_entry *); + + if (!head_e) + head_e = curr_e; + if (prev_e) + prev_e->next = curr_e; + + prev_e = curr_e; + entry = entry->next; + } + + desc->length = length; + desc->service_list = head_e; + + if (head) { + while (head->next) + head = head->next; + + head->next = (struct vidtv_psi_desc *)desc; + } + + return desc; +} + struct vidtv_psi_desc *vidtv_psi_desc_clone(struct vidtv_psi_desc *desc) { struct vidtv_psi_desc *head = NULL; @@ -396,6 +461,8 @@ struct vidtv_psi_desc *vidtv_psi_desc_clone(struct vidtv_psi_desc *desc) struct vidtv_psi_desc *curr = NULL; struct vidtv_psi_desc_service *service; + struct vidtv_psi_desc_network_name *desc_network_name; + struct vidtv_psi_desc_service_list *desc_service_list; while (desc) { switch (desc->type) { @@ -408,6 +475,20 @@ struct vidtv_psi_desc *vidtv_psi_desc_clone(struct vidtv_psi_desc *desc) service->provider_name); break; + case NETWORK_NAME_DESCRIPTOR: + desc_network_name = (struct vidtv_psi_desc_network_name *)desc; + curr = (struct vidtv_psi_desc *) + vidtv_psi_network_name_desc_init(head, + desc_network_name->network_name); + break; + + case SERVICE_LIST_DESCRIPTOR: + desc_service_list = (struct vidtv_psi_desc_service_list *)desc; + curr = (struct vidtv_psi_desc *) + vidtv_psi_service_list_desc_init(head, + desc_service_list->service_list); + break; + case REGISTRATION_DESCRIPTOR: default: curr = kzalloc(sizeof(*desc) + desc->length, GFP_KERNEL); @@ -433,6 +514,8 @@ void vidtv_psi_desc_destroy(struct vidtv_psi_desc *desc) { struct vidtv_psi_desc *curr = desc; struct vidtv_psi_desc *tmp = NULL; + struct vidtv_psi_desc_service_list_entry *sl_entry = NULL; + struct vidtv_psi_desc_service_list_entry *sl_entry_tmp = NULL; while (curr) { tmp = curr; @@ -448,6 +531,19 @@ void vidtv_psi_desc_destroy(struct vidtv_psi_desc *desc) /* nothing to do */ break; + case NETWORK_NAME_DESCRIPTOR: + kfree(((struct vidtv_psi_desc_network_name *)tmp)->network_name); + break; + + case SERVICE_LIST_DESCRIPTOR: + sl_entry = ((struct vidtv_psi_desc_service_list *)tmp)->service_list; + while (sl_entry) { + sl_entry_tmp = sl_entry; + sl_entry = sl_entry->next; + kfree(sl_entry_tmp); + } + break; + default: pr_warn_ratelimited("Possible leak: not handling descriptor type %d\n", tmp->type); @@ -519,6 +615,7 @@ static u32 vidtv_psi_desc_write_into(struct desc_write_args args) /* the number of bytes written by this function */ u32 nbytes = 0; struct psi_write_args psi_args = {}; + struct vidtv_psi_desc_service_list_entry *serv_list_entry = NULL; psi_args.dest_buf = args.dest_buf; psi_args.from = &args.desc->type; @@ -564,6 +661,28 @@ static u32 vidtv_psi_desc_write_into(struct desc_write_args args) nbytes += vidtv_psi_ts_psi_write_into(psi_args); break; + case NETWORK_NAME_DESCRIPTOR: + psi_args.dest_offset = args.dest_offset + nbytes; + psi_args.len = args.desc->length; + psi_args.from = ((struct vidtv_psi_desc_network_name *)args.desc)->network_name; + + nbytes += vidtv_psi_ts_psi_write_into(psi_args); + break; + + case SERVICE_LIST_DESCRIPTOR: + serv_list_entry = ((struct vidtv_psi_desc_service_list *)args.desc)->service_list; + while (serv_list_entry) { + psi_args.dest_offset = args.dest_offset + nbytes; + psi_args.len = sizeof(struct vidtv_psi_desc_service_list_entry) - + sizeof(struct vidtv_psi_desc_service_list_entry *); + psi_args.from = serv_list_entry; + + nbytes += vidtv_psi_ts_psi_write_into(psi_args); + + serv_list_entry = serv_list_entry->next; + } + break; + case REGISTRATION_DESCRIPTOR: default: psi_args.dest_offset = args.dest_offset + nbytes; @@ -682,7 +801,6 @@ void vidtv_psi_sdt_table_update_sec_len(struct vidtv_psi_table_sdt *sdt) } length += CRC_SIZE_IN_BYTES; - vidtv_psi_set_sec_len(&sdt->header, length); } @@ -1321,3 +1439,220 @@ struct vidtv_psi_table_pmt return NULL; /* not found */ } + +static void vidtv_psi_nit_table_update_sec_len(struct vidtv_psi_table_nit *nit) +{ + u16 length = 0; + struct vidtv_psi_table_transport *t = nit->transport; + u16 desc_loop_len; + u16 transport_loop_len = 0; + + /* + * from immediately after 'section_length' until + * 'network_descriptor_length' + */ + length += NIT_LEN_UNTIL_NETWORK_DESCRIPTOR_LEN; + + desc_loop_len = vidtv_psi_desc_comp_loop_len(nit->descriptor); + vidtv_psi_set_desc_loop_len(&nit->bitfield, desc_loop_len, 12); + + length += desc_loop_len; + + length += sizeof_field(struct vidtv_psi_table_nit, bitfield2); + + while (t) { + /* skip both pointers at the end */ + transport_loop_len += sizeof(struct vidtv_psi_table_transport) - + sizeof(struct vidtv_psi_desc *) - + sizeof(struct vidtv_psi_table_transport *); + + length += transport_loop_len; + + desc_loop_len = vidtv_psi_desc_comp_loop_len(t->descriptor); + vidtv_psi_set_desc_loop_len(&t->bitfield, desc_loop_len, 12); + + length += desc_loop_len; + + t = t->next; + } + + // Actually sets the transport stream loop len, maybe rename this function later + vidtv_psi_set_desc_loop_len(&nit->bitfield2, transport_loop_len, 12); + length += CRC_SIZE_IN_BYTES; + + vidtv_psi_set_sec_len(&nit->header, length); +} + +struct vidtv_psi_table_nit +*vidtv_psi_nit_table_init(u16 network_id, + u16 transport_stream_id, + char *network_name, + struct vidtv_psi_desc_service_list_entry *service_list) +{ + struct vidtv_psi_table_nit *nit = kzalloc(sizeof(*nit), GFP_KERNEL); + struct vidtv_psi_table_transport *transport = kzalloc(sizeof(*transport), GFP_KERNEL); + + const u16 SYNTAX = 0x1; + const u16 ONE = 0x1; + const u16 ONES = 0x03; + + nit->header.table_id = 0x40; // ACTUAL_NETWORK + + nit->header.bitfield = cpu_to_be16((SYNTAX << 15) | (ONE << 14) | (ONES << 12)); + + nit->header.id = cpu_to_be16(network_id); + nit->header.current_next = ONE; + + nit->header.version = 0x1f; + + nit->header.one2 = ONES; + nit->header.section_id = 0; + nit->header.last_section = 0; + + nit->bitfield = cpu_to_be16(0xf); + nit->bitfield2 = cpu_to_be16(0xf); + + nit->descriptor = (struct vidtv_psi_desc *) + vidtv_psi_network_name_desc_init(NULL, network_name); + + transport->transport_id = cpu_to_be16(transport_stream_id); + transport->network_id = cpu_to_be16(network_id); + transport->bitfield = cpu_to_be16(0xf); + transport->descriptor = (struct vidtv_psi_desc *) + vidtv_psi_service_list_desc_init(NULL, service_list); + + nit->transport = transport; + + vidtv_psi_nit_table_update_sec_len(nit); + + return nit; +} + +u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args args) +{ + /* the number of bytes written by this function */ + u32 nbytes = 0; + u32 crc = INITIAL_CRC; + + struct vidtv_psi_desc *table_descriptor = args.nit->descriptor; + struct vidtv_psi_table_transport *transport = args.nit->transport; + struct vidtv_psi_desc *transport_descriptor = (transport) ? + args.nit->transport->descriptor : + NULL; + + struct header_write_args h_args = {}; + struct psi_write_args psi_args = {}; + struct desc_write_args d_args = {}; + struct crc32_write_args c_args = {}; + + vidtv_psi_nit_table_update_sec_len(args.nit); + + h_args.dest_buf = args.buf; + h_args.dest_offset = args.offset; + h_args.h = &args.nit->header; + h_args.pid = VIDTV_NIT_PID; + h_args.continuity_counter = args.continuity_counter; + h_args.dest_buf_sz = args.buf_sz; + h_args.crc = &crc; + + nbytes += vidtv_psi_table_header_write_into(h_args); + + /* write the bitfield */ + psi_args.dest_buf = args.buf; + psi_args.from = &args.nit->bitfield; + psi_args.len = sizeof_field(struct vidtv_psi_table_nit, bitfield); + + psi_args.dest_offset = args.offset + nbytes; + psi_args.pid = VIDTV_NIT_PID; + psi_args.new_psi_section = false; + psi_args.continuity_counter = args.continuity_counter; + psi_args.is_crc = false; + psi_args.dest_buf_sz = args.buf_sz; + psi_args.crc = &crc; + + nbytes += vidtv_psi_ts_psi_write_into(psi_args); + + while (table_descriptor) { + /* write the descriptors, if any */ + d_args.dest_buf = args.buf; + d_args.dest_offset = args.offset + nbytes; + d_args.desc = table_descriptor; + d_args.pid = VIDTV_NIT_PID; + d_args.continuity_counter = args.continuity_counter; + d_args.dest_buf_sz = args.buf_sz; + d_args.crc = &crc; + + nbytes += vidtv_psi_desc_write_into(d_args); + + table_descriptor = table_descriptor->next; + } + + /* write the second bitfield */ + psi_args.dest_buf = args.buf; + psi_args.from = &args.nit->bitfield2; + psi_args.len = sizeof_field(struct vidtv_psi_table_nit, bitfield2); + psi_args.dest_offset = args.offset + nbytes; + psi_args.pid = VIDTV_NIT_PID; + + nbytes += vidtv_psi_ts_psi_write_into(psi_args); + + while (transport) { + /* write the transport sections, if any */ + psi_args.from = transport; + psi_args.len = sizeof_field(struct vidtv_psi_table_transport, transport_id) + + sizeof_field(struct vidtv_psi_table_transport, network_id) + + sizeof_field(struct vidtv_psi_table_transport, bitfield); + psi_args.dest_offset = args.offset + nbytes; + + nbytes += vidtv_psi_ts_psi_write_into(psi_args); + + while (transport_descriptor) { + /* write the transport descriptors, if any */ + d_args.dest_buf = args.buf; + d_args.dest_offset = args.offset + nbytes; + d_args.desc = transport_descriptor; + d_args.pid = VIDTV_NIT_PID; + d_args.continuity_counter = args.continuity_counter; + d_args.dest_buf_sz = args.buf_sz; + d_args.crc = &crc; + + nbytes += vidtv_psi_desc_write_into(d_args); + + transport_descriptor = transport_descriptor->next; + } + + transport = transport->next; + } + + c_args.dest_buf = args.buf; + c_args.dest_offset = args.offset + nbytes; + c_args.crc = cpu_to_be32(crc); + c_args.pid = VIDTV_NIT_PID; + c_args.continuity_counter = args.continuity_counter; + c_args.dest_buf_sz = args.buf_sz; + + /* Write the CRC32 at the end */ + nbytes += table_section_crc32_write_into(c_args); + + return nbytes; +} + +static void vidtv_psi_transport_destroy(struct vidtv_psi_table_transport *t) +{ + struct vidtv_psi_table_transport *curr_t = t; + struct vidtv_psi_table_transport *tmp_t = NULL; + + while (curr_t) { + tmp_t = curr_t; + curr_t = curr_t->next; + vidtv_psi_desc_destroy(tmp_t->descriptor); + kfree(tmp_t); + } +} + +void vidtv_psi_nit_table_destroy(struct vidtv_psi_table_nit *nit) +{ + vidtv_psi_desc_destroy(nit->descriptor); + vidtv_psi_transport_destroy(nit->transport); + kfree(nit); +} diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.h b/drivers/media/test-drivers/vidtv/vidtv_psi.h index 3f962cc78278..b5f2e6d7d1e8 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.h +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.h @@ -6,10 +6,6 @@ * technically be broken into one or more sections, we do not do this here, * hence 'table' and 'section' are interchangeable for vidtv. * - * This code currently supports three tables: PAT, PMT and SDT. These are the - * bare minimum to get userspace to recognize our MPEG transport stream. It can - * be extended to support more PSI tables in the future. - * * Copyright (C) 2020 Daniel W. S. Almeida */ @@ -27,12 +23,16 @@ #define PAT_LEN_UNTIL_LAST_SECTION_NUMBER 5 #define PMT_LEN_UNTIL_PROGRAM_INFO_LENGTH 9 #define SDT_LEN_UNTIL_RESERVED_FOR_FUTURE_USE 8 +#define NIT_LEN_UNTIL_NETWORK_DESCRIPTOR_LEN 7 #define MAX_SECTION_LEN 1021 #define VIDTV_PAT_PID 0 /* mandated by the specs */ #define VIDTV_SDT_PID 0x0011 /* mandated by the specs */ +#define VIDTV_NIT_PID 0x0010 /* mandated by the specs */ enum vidtv_psi_descriptors { REGISTRATION_DESCRIPTOR = 0x05, /* See ISO/IEC 13818-1 section 2.6.8 */ + NETWORK_NAME_DESCRIPTOR = 0x40, /* See ETSI EN 300 468 section 6.2.27 */ + SERVICE_LIST_DESCRIPTOR = 0x41, /* See ETSI EN 300 468 section 6.2.35 */ SERVICE_DESCRIPTOR = 0x48, /* See ETSI EN 300 468 section 6.2.33 */ }; @@ -90,6 +90,34 @@ struct vidtv_psi_desc_registration { u8 additional_identification_info[]; } __packed; +/** + * struct vidtv_psi_desc_network_name - A network name descriptor + * see ETSI EN 300 468 v1.15.1 section 6.2.27 + */ +struct vidtv_psi_desc_network_name { + struct vidtv_psi_desc *next; + u8 type; + u8 length; + char *network_name; +} __packed; + +struct vidtv_psi_desc_service_list_entry { + __be16 service_id; + u8 service_type; + struct vidtv_psi_desc_service_list_entry *next; +} __packed; + +/** + * struct vidtv_psi_desc_service_list - A service list descriptor + * see ETSI EN 300 468 v1.15.1 section 6.2.35 + */ +struct vidtv_psi_desc_service_list { + struct vidtv_psi_desc *next; + u8 type; + u8 length; + struct vidtv_psi_desc_service_list_entry *service_list; +} __packed; + /** * struct vidtv_psi_table_header - A header that is present for all PSI tables. */ @@ -290,6 +318,13 @@ struct vidtv_psi_desc_registration u8 *additional_ident_info, u32 additional_info_len); +struct vidtv_psi_desc_network_name +*vidtv_psi_network_name_desc_init(struct vidtv_psi_desc *head, char *network_name); + +struct vidtv_psi_desc_service_list +*vidtv_psi_service_list_desc_init(struct vidtv_psi_desc *head, + struct vidtv_psi_desc_service_list_entry *entry); + struct vidtv_psi_table_pat_program *vidtv_psi_pat_program_init(struct vidtv_psi_table_pat_program *head, u16 service_id, @@ -574,4 +609,79 @@ struct vidtv_psi_table_pmt *vidtv_psi_find_pmt_sec(struct vidtv_psi_table_pmt ** u16 vidtv_psi_get_pat_program_pid(struct vidtv_psi_table_pat_program *p); u16 vidtv_psi_pmt_stream_get_elem_pid(struct vidtv_psi_table_pmt_stream *s); +/** + * struct vidtv_psi_table_transport - A entry in the TS loop for the NIT and/or other tables. + * See ETSI 300 468 section 5.2.1 + * @transport_id: The TS ID being described + * @network_id: The network_id that contains the TS ID + * @bitfield: Contains the descriptor loop length + * @descriptor: A descriptor loop + * @next: Pointer to the next entry + * + */ +struct vidtv_psi_table_transport { + __be16 transport_id; + __be16 network_id; + __be16 bitfield; /* desc_len: 12, reserved: 4 */ + struct vidtv_psi_desc *descriptor; + struct vidtv_psi_table_transport *next; +} __packed; + +/** + * struct vidtv_psi_table_nit - A Network Information Table (NIT). See ETSI 300 + * 468 section 5.2.1 + * @header: A PSI table header + * @bitfield: Contains the network descriptor length + * @descriptor: A descriptor loop describing the network + * @bitfield2: Contains the transport stream loop length + * @transport: The transport stream loop + * + */ +struct vidtv_psi_table_nit { + struct vidtv_psi_table_header header; + __be16 bitfield; /* network_desc_len: 12, reserved:4 */ + struct vidtv_psi_desc *descriptor; + __be16 bitfield2; /* ts_loop_len: 12, reserved: 4 */ + struct vidtv_psi_table_transport *transport; +} __packed; + +struct vidtv_psi_table_nit +*vidtv_psi_nit_table_init(u16 network_id, + u16 transport_stream_id, + char *network_name, + struct vidtv_psi_desc_service_list_entry *service_list); + +/** + * struct vidtv_psi_nit_write_args - Arguments for writing a NIT section + * @buf: The destination buffer. + * @offset: The offset into the destination buffer. + * @nit: A pointer to the NIT + * @buf_sz: The size of the destination buffer. + * @continuity_counter: A pointer to the CC. Incremented on every new packet. + * + */ +struct vidtv_psi_nit_write_args { + char *buf; + u32 offset; + struct vidtv_psi_table_nit *nit; + u32 buf_sz; + u8 *continuity_counter; +}; + +/** + * vidtv_psi_nit_write_into - Write NIT as MPEG-TS packets into a buffer. + * @args: an instance of struct vidtv_psi_nit_write_args + * + * This function writes the MPEG TS packets for a NIT table into a buffer. + * Calling code will usually generate the NIT via a call to its init function + * and thus is responsible for freeing it. + * + * Return: The number of bytes written into the buffer. This is NOT + * equal to the size of the NIT, since more space is needed for TS headers during TS + * encapsulation. + */ +u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args args); + +void vidtv_psi_nit_table_destroy(struct vidtv_psi_table_nit *nit); + #endif // VIDTV_PSI_H -- cgit v1.2.3 From 7a7899f6f58e3270ccfd200ee63ebced5ddba3c9 Mon Sep 17 00:00:00 2001 From: "Daniel W. S. Almeida" Date: Sat, 31 Oct 2020 16:05:49 +0100 Subject: media: vidtv: psi: Implement an Event Information Table (EIT) Implement an Event Information Table (EIT) as per EN 300 468 5.2.4. The EIT provides information in chronological order regarding the events contained within each service. For now only present event information is supported. [mchehab+huawei@kernel.org: removed an extra blank line] Signed-off-by: Daniel W. S. Almeida Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- Documentation/driver-api/media/drivers/vidtv.rst | 8 +- drivers/media/test-drivers/vidtv/vidtv_channel.c | 71 ++++- drivers/media/test-drivers/vidtv/vidtv_channel.h | 3 + drivers/media/test-drivers/vidtv/vidtv_mux.c | 13 + drivers/media/test-drivers/vidtv/vidtv_mux.h | 2 + drivers/media/test-drivers/vidtv/vidtv_psi.c | 315 ++++++++++++++++++++++- drivers/media/test-drivers/vidtv/vidtv_psi.h | 120 ++++++++- 7 files changed, 523 insertions(+), 9 deletions(-) diff --git a/Documentation/driver-api/media/drivers/vidtv.rst b/Documentation/driver-api/media/drivers/vidtv.rst index 2d7ddf676b13..edaceef2808c 100644 --- a/Documentation/driver-api/media/drivers/vidtv.rst +++ b/Documentation/driver-api/media/drivers/vidtv.rst @@ -149,11 +149,11 @@ vidtv_psi.[ch] Because the generator is implemented in a separate file, it can be reused elsewhere in the media subsystem. - Currently vidtv supports working with 4 PSI tables: PAT, PMT, - SDT and NIT. + Currently vidtv supports working with 5 PSI tables: PAT, PMT, + SDT, NIT and EIT. The specification for PAT and PMT can be found in *ISO 13818-1: - Systems*, while the specification for the SDT, NIT can be found in *ETSI + Systems*, while the specification for the SDT, NIT, EIT can be found in *ETSI EN 300 468: Specification for Service Information (SI) in DVB systems*. @@ -197,6 +197,8 @@ vidtv_channel.[ch] #. Their programs will be concatenated to populate the PAT + #. Their events will be concatenated to populate the EIT + #. For each program in the PAT, a PMT section will be created #. The PMT section for a channel will be assigned its streams. diff --git a/drivers/media/test-drivers/vidtv/vidtv_channel.c b/drivers/media/test-drivers/vidtv/vidtv_channel.c index a246b49123d9..13e56544bb1e 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_channel.c +++ b/drivers/media/test-drivers/vidtv/vidtv_channel.c @@ -9,6 +9,7 @@ * When vidtv boots, it will create some hardcoded channels. * Their services will be concatenated to populate the SDT. * Their programs will be concatenated to populate the PAT + * Their events will be concatenated to populate the EIT * For each program in the PAT, a PMT section will be created * The PMT section for a channel will be assigned its streams. * Every stream will have its corresponding encoder polled to produce TS packets @@ -59,13 +60,17 @@ struct vidtv_channel char *name = ENCODING_ISO8859_15 "Beethoven"; char *provider = ENCODING_ISO8859_15 "LinuxTV.org"; + char *iso_language_code = ENCODING_ISO8859_15 "eng"; + char *event_name = ENCODING_ISO8859_15 "Beethoven Music"; + char *event_text = ENCODING_ISO8859_15 "Beethoven's 5th Symphony"; + const u16 s302m_beethoven_event_id = 1; struct vidtv_channel *s302m = kzalloc(sizeof(*s302m), GFP_KERNEL); struct vidtv_s302m_encoder_init_args encoder_args = {}; s302m->name = kstrdup(name, GFP_KERNEL); - s302m->service = vidtv_psi_sdt_service_init(NULL, s302m_service_id); + s302m->service = vidtv_psi_sdt_service_init(NULL, s302m_service_id, false, true); s302m->service->descriptor = (struct vidtv_psi_desc *) vidtv_psi_service_desc_init(NULL, @@ -94,6 +99,13 @@ struct vidtv_channel s302m->encoders = vidtv_s302m_encoder_init(encoder_args); + s302m->events = vidtv_psi_eit_event_init(NULL, s302m_beethoven_event_id); + s302m->events->descriptor = (struct vidtv_psi_desc *) + vidtv_psi_short_event_desc_init(NULL, + iso_language_code, + event_name, + event_text); + if (head) { while (head->next) head = head->next; @@ -104,6 +116,48 @@ struct vidtv_channel return s302m; } +static struct vidtv_psi_table_eit_event +*vidtv_channel_eit_event_cat_into_new(struct vidtv_mux *m) +{ + /* Concatenate the events */ + const struct vidtv_channel *cur_chnl = m->channels; + + struct vidtv_psi_table_eit_event *curr = NULL; + struct vidtv_psi_table_eit_event *head = NULL; + struct vidtv_psi_table_eit_event *tail = NULL; + + struct vidtv_psi_desc *desc = NULL; + u16 event_id; + + if (!cur_chnl) + return NULL; + + while (cur_chnl) { + curr = cur_chnl->events; + + if (!curr) + dev_warn_ratelimited(m->dev, + "No events found for channel %s\n", cur_chnl->name); + + while (curr) { + event_id = be16_to_cpu(curr->event_id); + tail = vidtv_psi_eit_event_init(tail, event_id); + + desc = vidtv_psi_desc_clone(curr->descriptor); + vidtv_psi_desc_assign(&tail->descriptor, desc); + + if (!head) + head = tail; + + curr = curr->next; + } + + cur_chnl = cur_chnl->next; + } + + return head; +} + static struct vidtv_psi_table_sdt_service *vidtv_channel_sdt_serv_cat_into_new(struct vidtv_mux *m) { @@ -129,7 +183,10 @@ static struct vidtv_psi_table_sdt_service while (curr) { service_id = be16_to_cpu(curr->service_id); - tail = vidtv_psi_sdt_service_init(tail, service_id); + tail = vidtv_psi_sdt_service_init(tail, + service_id, + curr->EIT_schedule, + curr->EIT_present_following); desc = vidtv_psi_desc_clone(curr->descriptor); vidtv_psi_desc_assign(&tail->descriptor, desc); @@ -297,6 +354,7 @@ void vidtv_channel_si_init(struct vidtv_mux *m) struct vidtv_psi_table_pat_program *programs = NULL; struct vidtv_psi_table_sdt_service *services = NULL; struct vidtv_psi_desc_service_list_entry *service_list = NULL; + struct vidtv_psi_table_eit_event *events = NULL; m->si.pat = vidtv_psi_pat_table_init(m->transport_stream_id); @@ -305,6 +363,8 @@ void vidtv_channel_si_init(struct vidtv_mux *m) programs = vidtv_channel_pat_prog_cat_into_new(m); services = vidtv_channel_sdt_serv_cat_into_new(m); + events = vidtv_channel_eit_event_cat_into_new(m); + /* look for a service descriptor for every service */ service_list = vidtv_channel_build_service_list(services); @@ -314,12 +374,17 @@ void vidtv_channel_si_init(struct vidtv_mux *m) m->network_name, service_list); + m->si.eit = vidtv_psi_eit_table_init(m->network_id, m->transport_stream_id); + /* assemble all programs and assign to PAT */ vidtv_psi_pat_program_assign(m->si.pat, programs); /* assemble all services and assign to SDT */ vidtv_psi_sdt_service_assign(m->si.sdt, services); + /* assemble all events and assign to EIT */ + vidtv_psi_eit_event_assign(m->si.eit, events); + m->si.pmt_secs = vidtv_psi_pmt_create_sec_for_each_pat_entry(m->si.pat, m->pcr_pid); vidtv_channel_pmt_match_sections(m->channels, @@ -342,6 +407,7 @@ void vidtv_channel_si_destroy(struct vidtv_mux *m) kfree(m->si.pmt_secs); vidtv_psi_sdt_table_destroy(m->si.sdt); vidtv_psi_nit_table_destroy(m->si.nit); + vidtv_psi_eit_table_destroy(m->si.eit); } void vidtv_channels_init(struct vidtv_mux *m) @@ -361,6 +427,7 @@ void vidtv_channels_destroy(struct vidtv_mux *m) vidtv_psi_pat_program_destroy(curr->program); vidtv_psi_pmt_stream_destroy(curr->streams); vidtv_channel_encoder_destroy(curr->encoders); + vidtv_psi_eit_event_destroy(curr->events); tmp = curr; curr = curr->next; diff --git a/drivers/media/test-drivers/vidtv/vidtv_channel.h b/drivers/media/test-drivers/vidtv/vidtv_channel.h index 2c3cba4313b0..40ed7fcdc5a1 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_channel.h +++ b/drivers/media/test-drivers/vidtv/vidtv_channel.h @@ -9,6 +9,7 @@ * When vidtv boots, it will create some hardcoded channels. * Their services will be concatenated to populate the SDT. * Their programs will be concatenated to populate the PAT + * Their events will be concatenated to populate the EIT * For each program in the PAT, a PMT section will be created * The PMT section for a channel will be assigned its streams. * Every stream will have its corresponding encoder polled to produce TS packets @@ -44,6 +45,7 @@ * Will be concatenated into the PAT. * @streams: A stream loop used to populate the PMT section for 'program' * @encoders: A encoder loop. There must be one encoder for each stream. + * @events: Optional event information. This will feed into the EIT. * @next: Optionally chain this channel. */ struct vidtv_channel { @@ -54,6 +56,7 @@ struct vidtv_channel { struct vidtv_psi_table_pat_program *program; struct vidtv_psi_table_pmt_stream *streams; struct vidtv_encoder *encoders; + struct vidtv_psi_table_eit_event *events; struct vidtv_channel *next; }; diff --git a/drivers/media/test-drivers/vidtv/vidtv_mux.c b/drivers/media/test-drivers/vidtv/vidtv_mux.c index 2a960e87c39c..c3646dd269dd 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_mux.c +++ b/drivers/media/test-drivers/vidtv/vidtv_mux.c @@ -76,6 +76,8 @@ static void vidtv_mux_pid_ctx_init(struct vidtv_mux *m) vidtv_mux_create_pid_ctx_once(m, VIDTV_SDT_PID); /* push the NIT pid ctx */ vidtv_mux_create_pid_ctx_once(m, VIDTV_NIT_PID); + /* push the EIT pid ctx */ + vidtv_mux_create_pid_ctx_once(m, VIDTV_EIT_PID); /* add a ctx for all PMT sections */ while (p) { @@ -120,11 +122,13 @@ static u32 vidtv_mux_push_si(struct vidtv_mux *m) struct vidtv_mux_pid_ctx *pmt_ctx; struct vidtv_mux_pid_ctx *sdt_ctx; struct vidtv_mux_pid_ctx *nit_ctx; + struct vidtv_mux_pid_ctx *eit_ctx; struct vidtv_psi_pat_write_args pat_args = {}; struct vidtv_psi_pmt_write_args pmt_args = {}; struct vidtv_psi_sdt_write_args sdt_args = {}; struct vidtv_psi_nit_write_args nit_args = {}; + struct vidtv_psi_eit_write_args eit_args = {}; u32 nbytes; /* the number of bytes written by this function */ u16 pmt_pid; @@ -133,6 +137,7 @@ static u32 vidtv_mux_push_si(struct vidtv_mux *m) pat_ctx = vidtv_mux_get_pid_ctx(m, VIDTV_PAT_PID); sdt_ctx = vidtv_mux_get_pid_ctx(m, VIDTV_SDT_PID); nit_ctx = vidtv_mux_get_pid_ctx(m, VIDTV_NIT_PID); + eit_ctx = vidtv_mux_get_pid_ctx(m, VIDTV_EIT_PID); pat_args.buf = m->mux_buf; pat_args.offset = m->mux_buf_offset; @@ -182,6 +187,14 @@ static u32 vidtv_mux_push_si(struct vidtv_mux *m) m->mux_buf_offset += vidtv_psi_nit_write_into(nit_args); + eit_args.buf = m->mux_buf; + eit_args.offset = m->mux_buf_offset; + eit_args.eit = m->si.eit; + eit_args.buf_sz = m->mux_buf_sz; + eit_args.continuity_counter = &eit_ctx->cc; + + m->mux_buf_offset += vidtv_psi_eit_write_into(eit_args); + nbytes = m->mux_buf_offset - initial_offset; m->num_streamed_si++; diff --git a/drivers/media/test-drivers/vidtv/vidtv_mux.h b/drivers/media/test-drivers/vidtv/vidtv_mux.h index 5dfbe30c2ac8..6eeb09fbfe4d 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_mux.h +++ b/drivers/media/test-drivers/vidtv/vidtv_mux.h @@ -58,6 +58,7 @@ struct vidtv_mux_timing { * @pat: The PAT in use by the muxer. * @pmt_secs: The PMT sections in use by the muxer. One for each program in the PAT. * @sdt: The SDT in use by the muxer. + * @eit: the EIT in use by the muxer. */ struct vidtv_mux_si { /* the SI tables */ @@ -65,6 +66,7 @@ struct vidtv_mux_si { struct vidtv_psi_table_pmt **pmt_secs; /* the PMT sections */ struct vidtv_psi_table_sdt *sdt; struct vidtv_psi_table_nit *nit; + struct vidtv_psi_table_eit *eit; }; /** diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c index 0de6d646a483..b0b476545d65 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.c +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c @@ -28,6 +28,7 @@ #define CRC_SIZE_IN_BYTES 4 #define MAX_VERSION_NUM 32 #define INITIAL_CRC 0xffffffff +#define ISO_LANGUAGE_CODE_LEN 3 static const u32 CRC_LUT[256] = { /* from libdvbv5 */ @@ -454,6 +455,51 @@ struct vidtv_psi_desc_service_list return desc; } +struct vidtv_psi_desc_short_event +*vidtv_psi_short_event_desc_init(struct vidtv_psi_desc *head, + char *iso_language_code, + char *event_name, + char *text) +{ + struct vidtv_psi_desc_short_event *desc; + u32 event_name_len = event_name ? strlen(event_name) : 0; + u32 text_len = text ? strlen(text) : 0; + u32 iso_len = iso_language_code ? strlen(iso_language_code) : 0; + + desc = kzalloc(sizeof(*desc), GFP_KERNEL); + + desc->type = SHORT_EVENT_DESCRIPTOR; + + desc->length = ISO_LANGUAGE_CODE_LEN + + sizeof_field(struct vidtv_psi_desc_short_event, event_name_len) + + event_name_len + + sizeof_field(struct vidtv_psi_desc_short_event, text_len) + + text_len; + + desc->event_name_len = event_name_len; + desc->text_len = text_len; + + if (iso_len != ISO_LANGUAGE_CODE_LEN) + iso_language_code = "eng"; + + desc->iso_language_code = kstrdup(iso_language_code, GFP_KERNEL); + + if (event_name && event_name_len) + desc->event_name = kstrdup(event_name, GFP_KERNEL); + + if (text && text_len) + desc->text = kstrdup(text, GFP_KERNEL); + + if (head) { + while (head->next) + head = head->next; + + head->next = (struct vidtv_psi_desc *)desc; + } + + return desc; +} + struct vidtv_psi_desc *vidtv_psi_desc_clone(struct vidtv_psi_desc *desc) { struct vidtv_psi_desc *head = NULL; @@ -463,6 +509,7 @@ struct vidtv_psi_desc *vidtv_psi_desc_clone(struct vidtv_psi_desc *desc) struct vidtv_psi_desc_service *service; struct vidtv_psi_desc_network_name *desc_network_name; struct vidtv_psi_desc_service_list *desc_service_list; + struct vidtv_psi_desc_short_event *desc_short_event; while (desc) { switch (desc->type) { @@ -489,6 +536,15 @@ struct vidtv_psi_desc *vidtv_psi_desc_clone(struct vidtv_psi_desc *desc) desc_service_list->service_list); break; + case SHORT_EVENT_DESCRIPTOR: + desc_short_event = (struct vidtv_psi_desc_short_event *)desc; + curr = (struct vidtv_psi_desc *) + vidtv_psi_short_event_desc_init(head, + desc_short_event->iso_language_code, + desc_short_event->event_name, + desc_short_event->text); + break; + case REGISTRATION_DESCRIPTOR: default: curr = kzalloc(sizeof(*desc) + desc->length, GFP_KERNEL); @@ -544,6 +600,12 @@ void vidtv_psi_desc_destroy(struct vidtv_psi_desc *desc) } break; + case SHORT_EVENT_DESCRIPTOR: + kfree(((struct vidtv_psi_desc_short_event *)tmp)->iso_language_code); + kfree(((struct vidtv_psi_desc_short_event *)tmp)->event_name); + kfree(((struct vidtv_psi_desc_short_event *)tmp)->text); + break; + default: pr_warn_ratelimited("Possible leak: not handling descriptor type %d\n", tmp->type); @@ -683,6 +745,41 @@ static u32 vidtv_psi_desc_write_into(struct desc_write_args args) } break; + case SHORT_EVENT_DESCRIPTOR: + psi_args.dest_offset = args.dest_offset + nbytes; + psi_args.len = ISO_LANGUAGE_CODE_LEN; + psi_args.from = ((struct vidtv_psi_desc_short_event *) + args.desc)->iso_language_code; + + nbytes += vidtv_psi_ts_psi_write_into(psi_args); + + psi_args.dest_offset = args.dest_offset + nbytes; + psi_args.len = sizeof_field(struct vidtv_psi_desc_short_event, event_name_len); + psi_args.from = &((struct vidtv_psi_desc_short_event *) + args.desc)->event_name_len; + + nbytes += vidtv_psi_ts_psi_write_into(psi_args); + + psi_args.dest_offset = args.dest_offset + nbytes; + psi_args.len = ((struct vidtv_psi_desc_short_event *)args.desc)->event_name_len; + psi_args.from = ((struct vidtv_psi_desc_short_event *)args.desc)->event_name; + + nbytes += vidtv_psi_ts_psi_write_into(psi_args); + + psi_args.dest_offset = args.dest_offset + nbytes; + psi_args.len = sizeof_field(struct vidtv_psi_desc_short_event, text_len); + psi_args.from = &((struct vidtv_psi_desc_short_event *)args.desc)->text_len; + + nbytes += vidtv_psi_ts_psi_write_into(psi_args); + + psi_args.dest_offset = args.dest_offset + nbytes; + psi_args.len = ((struct vidtv_psi_desc_short_event *)args.desc)->text_len; + psi_args.from = ((struct vidtv_psi_desc_short_event *)args.desc)->text; + + nbytes += vidtv_psi_ts_psi_write_into(psi_args); + + break; + case REGISTRATION_DESCRIPTOR: default: psi_args.dest_offset = args.dest_offset + nbytes; @@ -1334,7 +1431,9 @@ void vidtv_psi_sdt_table_destroy(struct vidtv_psi_table_sdt *sdt) struct vidtv_psi_table_sdt_service *vidtv_psi_sdt_service_init(struct vidtv_psi_table_sdt_service *head, - u16 service_id) + u16 service_id, + bool eit_schedule, + bool eit_present_following) { struct vidtv_psi_table_sdt_service *service; @@ -1347,8 +1446,8 @@ struct vidtv_psi_table_sdt_service * corresponding program_map_section */ service->service_id = cpu_to_be16(service_id); - service->EIT_schedule = 0x0; - service->EIT_present_following = 0x0; + service->EIT_schedule = eit_schedule; + service->EIT_present_following = eit_present_following; service->reserved = 0x3f; service->bitfield = cpu_to_be16(RUNNING << 13); @@ -1656,3 +1755,213 @@ void vidtv_psi_nit_table_destroy(struct vidtv_psi_table_nit *nit) vidtv_psi_transport_destroy(nit->transport); kfree(nit); } + +void vidtv_psi_eit_table_update_sec_len(struct vidtv_psi_table_eit *eit) +{ + u16 length = 0; + struct vidtv_psi_table_eit_event *e = eit->event; + u16 desc_loop_len; + + /* + * from immediately after 'section_length' until + * 'last_table_id' + */ + length += EIT_LEN_UNTIL_LAST_TABLE_ID; + + while (e) { + /* skip both pointers at the end */ + length += sizeof(struct vidtv_psi_table_eit_event) - + sizeof(struct vidtv_psi_desc *) - + sizeof(struct vidtv_psi_table_eit_event *); + + desc_loop_len = vidtv_psi_desc_comp_loop_len(e->descriptor); + vidtv_psi_set_desc_loop_len(&e->bitfield, desc_loop_len, 12); + + length += desc_loop_len; + + e = e->next; + } + + length += CRC_SIZE_IN_BYTES; + + vidtv_psi_set_sec_len(&eit->header, length); +} + +void vidtv_psi_eit_event_assign(struct vidtv_psi_table_eit *eit, + struct vidtv_psi_table_eit_event *e) +{ + if (e == eit->event) + return; + + eit->event = e; + vidtv_psi_eit_table_update_sec_len(eit); + + if (vidtv_psi_get_sec_len(&eit->header) > EIT_MAX_SECTION_LEN) + vidtv_psi_eit_event_assign(eit, NULL); + + vidtv_psi_update_version_num(&eit->header); +} + +struct vidtv_psi_table_eit +*vidtv_psi_eit_table_init(u16 network_id, + u16 transport_stream_id) +{ + struct vidtv_psi_table_eit *eit = kzalloc(sizeof(*eit), GFP_KERNEL); + + const u16 SYNTAX = 0x1; + const u16 ONE = 0x1; + const u16 ONES = 0x03; + + eit->header.table_id = 0x4e; //actual_transport_stream: present/following + + eit->header.bitfield = cpu_to_be16((SYNTAX << 15) | (ONE << 14) | (ONES << 12)); + + eit->header.id = cpu_to_be16(network_id); + eit->header.current_next = ONE; + + eit->header.version = 0x1f; + + eit->header.one2 = ONES; + eit->header.section_id = 0; + eit->header.last_section = 0; + + eit->transport_id = cpu_to_be16(transport_stream_id); + eit->network_id = cpu_to_be16(network_id); + + eit->last_segment = eit->header.last_section; /* not implemented */ + eit->last_table_id = eit->header.table_id; /* not implemented */ + + vidtv_psi_eit_table_update_sec_len(eit); + + return eit; +} + +u32 vidtv_psi_eit_write_into(struct vidtv_psi_eit_write_args args) +{ + u32 nbytes = 0; + u32 crc = INITIAL_CRC; + + struct vidtv_psi_table_eit_event *event = args.eit->event; + struct vidtv_psi_desc *event_descriptor = (args.eit->event) ? + args.eit->event->descriptor : + NULL; + + struct header_write_args h_args = {}; + struct psi_write_args psi_args = {}; + struct desc_write_args d_args = {}; + struct crc32_write_args c_args = {}; + + vidtv_psi_eit_table_update_sec_len(args.eit); + + h_args.dest_buf = args.buf; + h_args.dest_offset = args.offset; + h_args.h = &args.eit->header; + h_args.pid = VIDTV_EIT_PID; + h_args.continuity_counter = args.continuity_counter; + h_args.dest_buf_sz = args.buf_sz; + h_args.crc = &crc; + + nbytes += vidtv_psi_table_header_write_into(h_args); + + psi_args.dest_buf = args.buf; + psi_args.from = &args.eit->transport_id; + + psi_args.len = sizeof_field(struct vidtv_psi_table_eit, transport_id) + + sizeof_field(struct vidtv_psi_table_eit, network_id) + + sizeof_field(struct vidtv_psi_table_eit, last_segment) + + sizeof_field(struct vidtv_psi_table_eit, last_table_id); + + psi_args.dest_offset = args.offset + nbytes; + psi_args.pid = VIDTV_EIT_PID; + psi_args.new_psi_section = false; + psi_args.continuity_counter = args.continuity_counter; + psi_args.is_crc = false; + psi_args.dest_buf_sz = args.buf_sz; + psi_args.crc = &crc; + + nbytes += vidtv_psi_ts_psi_write_into(psi_args); + + while (event) { + /* copy the events, if any */ + psi_args.from = event; + /* skip both pointers at the end */ + psi_args.len = sizeof(struct vidtv_psi_table_eit_event) - + sizeof(struct vidtv_psi_desc *) - + sizeof(struct vidtv_psi_table_eit_event *); + psi_args.dest_offset = args.offset + nbytes; + + nbytes += vidtv_psi_ts_psi_write_into(psi_args); + + event_descriptor = event->descriptor; + + while (event_descriptor) { + /* copy the event descriptors, if any */ + d_args.dest_buf = args.buf; + d_args.dest_offset = args.offset + nbytes; + d_args.desc = event_descriptor; + d_args.pid = VIDTV_EIT_PID; + d_args.continuity_counter = args.continuity_counter; + d_args.dest_buf_sz = args.buf_sz; + d_args.crc = &crc; + + nbytes += vidtv_psi_desc_write_into(d_args); + + event_descriptor = event_descriptor->next; + } + + event = event->next; + } + + c_args.dest_buf = args.buf; + c_args.dest_offset = args.offset + nbytes; + c_args.crc = cpu_to_be32(crc); + c_args.pid = VIDTV_EIT_PID; + c_args.continuity_counter = args.continuity_counter; + c_args.dest_buf_sz = args.buf_sz; + + /* Write the CRC at the end */ + nbytes += table_section_crc32_write_into(c_args); + + return nbytes; +} + +struct vidtv_psi_table_eit_event +*vidtv_psi_eit_event_init(struct vidtv_psi_table_eit_event *head, u16 event_id) +{ + struct vidtv_psi_table_eit_event *e = kzalloc(sizeof(*e), GFP_KERNEL); + const u8 DURATION_ONE_HOUR[] = {1, 0, 0}; + + e->event_id = cpu_to_be16(event_id); + memset(e->start_time, 0xff, sizeof(e->start_time)); //todo: 0xff means 'unspecified' + memcpy(e->duration, DURATION_ONE_HOUR, sizeof(e->duration)); //todo, default to this for now + + e->bitfield = cpu_to_be16(RUNNING << 13); + + if (head) { + while (head->next) + head = head->next; + + head->next = e; + } + + return e; +} + +void vidtv_psi_eit_event_destroy(struct vidtv_psi_table_eit_event *e) +{ + struct vidtv_psi_table_eit_event *curr_e = e; + struct vidtv_psi_table_eit_event *tmp_e = NULL; + + while (curr_e) { + tmp_e = curr_e; + curr_e = curr_e->next; + vidtv_psi_desc_destroy(tmp_e->descriptor); + kfree(tmp_e); + } +} + +void vidtv_psi_eit_table_destroy(struct vidtv_psi_table_eit *eit) +{ + vidtv_psi_eit_event_destroy(eit->event); + kfree(eit); +} diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.h b/drivers/media/test-drivers/vidtv/vidtv_psi.h index b5f2e6d7d1e8..58efe54f7a5a 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.h +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.h @@ -24,16 +24,20 @@ #define PMT_LEN_UNTIL_PROGRAM_INFO_LENGTH 9 #define SDT_LEN_UNTIL_RESERVED_FOR_FUTURE_USE 8 #define NIT_LEN_UNTIL_NETWORK_DESCRIPTOR_LEN 7 +#define EIT_LEN_UNTIL_LAST_TABLE_ID 11 #define MAX_SECTION_LEN 1021 +#define EIT_MAX_SECTION_LEN 4093 /* see ETSI 300 468 v.1.10.1 p. 26 */ #define VIDTV_PAT_PID 0 /* mandated by the specs */ #define VIDTV_SDT_PID 0x0011 /* mandated by the specs */ #define VIDTV_NIT_PID 0x0010 /* mandated by the specs */ +#define VIDTV_EIT_PID 0x0012 /*mandated by the specs */ enum vidtv_psi_descriptors { REGISTRATION_DESCRIPTOR = 0x05, /* See ISO/IEC 13818-1 section 2.6.8 */ NETWORK_NAME_DESCRIPTOR = 0x40, /* See ETSI EN 300 468 section 6.2.27 */ SERVICE_LIST_DESCRIPTOR = 0x41, /* See ETSI EN 300 468 section 6.2.35 */ SERVICE_DESCRIPTOR = 0x48, /* See ETSI EN 300 468 section 6.2.33 */ + SHORT_EVENT_DESCRIPTOR = 0x4d, /* See ETSI EN 300 468 section 6.2.37 */ }; enum vidtv_psi_stream_types { @@ -118,6 +122,27 @@ struct vidtv_psi_desc_service_list { struct vidtv_psi_desc_service_list_entry *service_list; } __packed; +/** + * struct vidtv_psi_desc_short_event - A short event descriptor + * see ETSI EN 300 468 v1.15.1 section 6.2.37 + */ +struct vidtv_psi_desc_short_event { + struct vidtv_psi_desc *next; + u8 type; + u8 length; + char *iso_language_code; + u8 event_name_len; + char *event_name; + u8 text_len; + char *text; +} __packed; + +struct vidtv_psi_desc_short_event +*vidtv_psi_short_event_desc_init(struct vidtv_psi_desc *head, + char *iso_language_code, + char *event_name, + char *text); + /** * struct vidtv_psi_table_header - A header that is present for all PSI tables. */ @@ -344,7 +369,9 @@ struct vidtv_psi_table_sdt *vidtv_psi_sdt_table_init(u16 transport_stream_id); struct vidtv_psi_table_sdt_service* vidtv_psi_sdt_service_init(struct vidtv_psi_table_sdt_service *head, - u16 service_id); + u16 service_id, + bool eit_schedule, + bool eit_present_following); void vidtv_psi_desc_destroy(struct vidtv_psi_desc *desc); @@ -684,4 +711,95 @@ u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args args); void vidtv_psi_nit_table_destroy(struct vidtv_psi_table_nit *nit); +/** + * struct vidtv_psi_desc_short_event - A short event descriptor + * see ETSI EN 300 468 v1.15.1 section 6.2.37 + */ +struct vidtv_psi_table_eit_event { + __be16 event_id; + u8 start_time[5]; + u8 duration[3]; + __be16 bitfield; /* desc_length: 12, free_CA_mode: 1, running_status: 1 */ + struct vidtv_psi_desc *descriptor; + struct vidtv_psi_table_eit_event *next; +} __packed; + +/* + * struct vidtv_psi_table_eit - A Event Information Table (EIT) + * See ETSI 300 468 section 5.2.4 + */ +struct vidtv_psi_table_eit { + struct vidtv_psi_table_header header; + __be16 transport_id; + __be16 network_id; + u8 last_segment; + u8 last_table_id; + struct vidtv_psi_table_eit_event *event; +} __packed; + +struct vidtv_psi_table_eit +*vidtv_psi_eit_table_init(u16 network_id, + u16 transport_stream_id); + +/** + * struct vidtv_psi_eit_write_args - Arguments for writing an EIT section + * @buf: The destination buffer. + * @offset: The offset into the destination buffer. + * @nit: A pointer to the NIT + * @buf_sz: The size of the destination buffer. + * @continuity_counter: A pointer to the CC. Incremented on every new packet. + * + */ +struct vidtv_psi_eit_write_args { + char *buf; + u32 offset; + struct vidtv_psi_table_eit *eit; + u32 buf_sz; + u8 *continuity_counter; +}; + +/** + * vidtv_psi_eit_write_into - Write EIT as MPEG-TS packets into a buffer. + * @args: an instance of struct vidtv_psi_nit_write_args + * + * This function writes the MPEG TS packets for a EIT table into a buffer. + * Calling code will usually generate the EIT via a call to its init function + * and thus is responsible for freeing it. + * + * Return: The number of bytes written into the buffer. This is NOT + * equal to the size of the EIT, since more space is needed for TS headers during TS + * encapsulation. + */ +u32 vidtv_psi_eit_write_into(struct vidtv_psi_eit_write_args args); + +void vidtv_psi_eit_table_destroy(struct vidtv_psi_table_eit *eit); + +/** + * vidtv_psi_eit_table_update_sec_len - Recompute and update the EIT section length. + * @eit: The EIT whose length is to be updated. + * + * This will traverse the table and accumulate the length of its components, + * which is then used to replace the 'section_length' field. + * + * If section_length > EIT_MAX_SECTION_LEN, the operation fails. + */ +void vidtv_psi_eit_table_update_sec_len(struct vidtv_psi_table_eit *eit); + +/** + * vidtv_psi_eit_event_assign - Assigns the event loop to the EIT. + * @eit: The EIT to assign to. + * @e: The event loop + * + * This will free the previous event loop in the table. + * This will assign ownership of the stream loop to the table, i.e. the table + * will free this stream loop when a call to its destroy function is made. + */ +void vidtv_psi_eit_event_assign(struct vidtv_psi_table_eit *eit, + struct vidtv_psi_table_eit_event *e); + +struct vidtv_psi_table_eit_event +*vidtv_psi_eit_event_init(struct vidtv_psi_table_eit_event *head, u16 event_id); + +void vidtv_psi_eit_event_destroy(struct vidtv_psi_table_eit_event *e); + #endif // VIDTV_PSI_H -- cgit v1.2.3 From 84306c96b1c249d5eab6af9f86110a2d80b56010 Mon Sep 17 00:00:00 2001 From: "Daniel W. S. Almeida" Date: Sat, 31 Oct 2020 16:05:50 +0100 Subject: media: vidtv: psi: extract descriptor chaining code into a helper The code to append a descriptor to the end of a chain is repeated throughout the psi generator code. Extract it into its own helper function to avoid cluttering. Signed-off-by: Daniel W. S. Almeida Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_psi.c | 49 +++++++++------------------- 1 file changed, 15 insertions(+), 34 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c index b0b476545d65..ad2957efa483 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.c +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c @@ -314,6 +314,16 @@ static u32 table_section_crc32_write_into(struct crc32_write_args args) return nbytes; } +static void vidtv_psi_desc_chain(struct vidtv_psi_desc *head, struct vidtv_psi_desc *desc) +{ + if (head) { + while (head->next) + head = head->next; + + head->next = desc; + } +} + struct vidtv_psi_desc_service *vidtv_psi_service_desc_init(struct vidtv_psi_desc *head, enum service_type service_type, char *service_name, @@ -345,12 +355,7 @@ struct vidtv_psi_desc_service *vidtv_psi_service_desc_init(struct vidtv_psi_desc if (provider_name && provider_name_len) desc->provider_name = kstrdup(provider_name, GFP_KERNEL); - if (head) { - while (head->next) - head = head->next; - - head->next = (struct vidtv_psi_desc *)desc; - } + vidtv_psi_desc_chain(head, (struct vidtv_psi_desc *)desc); return desc; } @@ -376,13 +381,7 @@ struct vidtv_psi_desc_registration additional_ident_info, additional_info_len); - if (head) { - while (head->next) - head = head->next; - - head->next = (struct vidtv_psi_desc *)desc; - } - + vidtv_psi_desc_chain(head, (struct vidtv_psi_desc *)desc); return desc; } @@ -401,13 +400,7 @@ struct vidtv_psi_desc_network_name if (network_name && network_name_len) desc->network_name = kstrdup(network_name, GFP_KERNEL); - if (head) { - while (head->next) - head = head->next; - - head->next = (struct vidtv_psi_desc *)desc; - } - + vidtv_psi_desc_chain(head, (struct vidtv_psi_desc *)desc); return desc; } @@ -445,13 +438,7 @@ struct vidtv_psi_desc_service_list desc->length = length; desc->service_list = head_e; - if (head) { - while (head->next) - head = head->next; - - head->next = (struct vidtv_psi_desc *)desc; - } - + vidtv_psi_desc_chain(head, (struct vidtv_psi_desc *)desc); return desc; } @@ -490,13 +477,7 @@ struct vidtv_psi_desc_short_event if (text && text_len) desc->text = kstrdup(text, GFP_KERNEL); - if (head) { - while (head->next) - head = head->next; - - head->next = (struct vidtv_psi_desc *)desc; - } - + vidtv_psi_desc_chain(head, (struct vidtv_psi_desc *)desc); return desc; } -- cgit v1.2.3 From 99b99d135ee3fd3a073556b5b646a69b1793f3a2 Mon Sep 17 00:00:00 2001 From: "Daniel W. S. Almeida" Date: Sat, 31 Oct 2020 16:05:51 +0100 Subject: media: vidtv: Move s302m specific fields into encoder context A few fields used only by the tone generator in the s302m encoder are stored in struct vidtv_encoder. Move them into struct vidtv_s302m_ctx instead. While we are at it: fix a checkpatch warning for long lines. Signed-off-by: Daniel W. S. Almeida Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_encoder.h | 3 --- drivers/media/test-drivers/vidtv/vidtv_s302m.c | 25 +++++++++++++----------- drivers/media/test-drivers/vidtv/vidtv_s302m.h | 3 +++ 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_encoder.h b/drivers/media/test-drivers/vidtv/vidtv_encoder.h index 65d81daef4c3..f742d566fbcb 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_encoder.h +++ b/drivers/media/test-drivers/vidtv/vidtv_encoder.h @@ -131,9 +131,6 @@ struct vidtv_encoder { u32 encoder_buf_offset; u64 sample_count; - int last_duration; - int note_offset; - enum musical_notes last_tone; struct vidtv_access_unit *access_units; diff --git a/drivers/media/test-drivers/vidtv/vidtv_s302m.c b/drivers/media/test-drivers/vidtv/vidtv_s302m.c index a447ccbd68d5..aacf8110d874 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_s302m.c +++ b/drivers/media/test-drivers/vidtv/vidtv_s302m.c @@ -230,36 +230,38 @@ static u16 vidtv_s302m_get_sample(struct vidtv_encoder *e) { u16 sample; int pos; + struct vidtv_s302m_ctx *ctx = e->ctx; if (!e->src_buf) { /* * Simple tone generator: play the tones at the * beethoven_5th_symphony array. */ - if (e->last_duration <= 0) { + if (ctx->last_duration <= 0) { if (e->src_buf_offset >= ARRAY_SIZE(beethoven_5th_symphony)) e->src_buf_offset = 0; - e->last_tone = beethoven_5th_symphony[e->src_buf_offset].note; - e->last_duration = beethoven_5th_symphony[e->src_buf_offset].duration * S302M_SAMPLING_RATE_HZ / COMPASS / 5; + ctx->last_tone = beethoven_5th_symphony[e->src_buf_offset].note; + ctx->last_duration = beethoven_5th_symphony[e->src_buf_offset].duration * + S302M_SAMPLING_RATE_HZ / COMPASS / 5; e->src_buf_offset++; - e->note_offset = 0; + ctx->note_offset = 0; } else { - e->last_duration--; + ctx->last_duration--; } /* Handle silent */ - if (!e->last_tone) { + if (!ctx->last_tone) { e->src_buf_offset = 0; return 0x8000; } - pos = (2 * PI * e->note_offset * e->last_tone / S302M_SAMPLING_RATE_HZ); + pos = (2 * PI * ctx->note_offset * ctx->last_tone / S302M_SAMPLING_RATE_HZ); if (pos == 360) - e->note_offset = 0; + ctx->note_offset = 0; else - e->note_offset++; + ctx->note_offset++; return (fixp_sin32(pos % (2 * PI)) >> 16) + 0x8000; } @@ -442,6 +444,7 @@ struct vidtv_encoder { struct vidtv_encoder *e = kzalloc(sizeof(*e), GFP_KERNEL); u32 priv_sz = sizeof(struct vidtv_s302m_ctx); + struct vidtv_s302m_ctx *ctx = kzalloc(priv_sz, GFP_KERNEL); e->id = S302M; @@ -453,14 +456,14 @@ struct vidtv_encoder e->encoder_buf_offset = 0; e->sample_count = 0; - e->last_duration = 0; e->src_buf = (args.src_buf) ? args.src_buf : NULL; e->src_buf_sz = (args.src_buf) ? args.src_buf_sz : 0; e->src_buf_offset = 0; e->is_video_encoder = false; - e->ctx = kzalloc(priv_sz, GFP_KERNEL); + e->ctx = ctx; + ctx->last_duration = 0; e->encode = vidtv_s302m_encode; e->clear = vidtv_s302m_clear; diff --git a/drivers/media/test-drivers/vidtv/vidtv_s302m.h b/drivers/media/test-drivers/vidtv/vidtv_s302m.h index eca5e3150ede..b1bbe521e766 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_s302m.h +++ b/drivers/media/test-drivers/vidtv/vidtv_s302m.h @@ -39,6 +39,9 @@ struct vidtv_s302m_ctx { struct vidtv_encoder *enc; u32 frame_index; u32 au_count; + int last_duration; + int note_offset; + enum musical_notes last_tone; }; /** -- cgit v1.2.3 From c2b6ca661ae209ea3eeb71ea38ef3fa7dca9c3c1 Mon Sep 17 00:00:00 2001 From: "Daniel W. S. Almeida" Date: Sat, 31 Oct 2020 16:05:52 +0100 Subject: media: vidtv: psi: fix missing assignments in while loops Some variables were only assigned once but were used in while loops as if they had been updated at every iteration. Fix this. Signed-off-by: Daniel W. S. Almeida Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_psi.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c index ad2957efa483..4dda5b0004a3 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.c +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c @@ -1175,9 +1175,7 @@ u32 vidtv_psi_pmt_write_into(struct vidtv_psi_pmt_write_args args) struct vidtv_psi_desc *table_descriptor = args.pmt->descriptor; struct vidtv_psi_table_pmt_stream *stream = args.pmt->stream; - struct vidtv_psi_desc *stream_descriptor = (stream) ? - args.pmt->stream->descriptor : - NULL; + struct vidtv_psi_desc *stream_descriptor; struct header_write_args h_args = {}; struct psi_write_args psi_args = {}; @@ -1237,6 +1235,8 @@ u32 vidtv_psi_pmt_write_into(struct vidtv_psi_pmt_write_args args) nbytes += vidtv_psi_ts_psi_write_into(psi_args); + stream_descriptor = stream->descriptor; + while (stream_descriptor) { /* write the stream descriptors, if any */ d_args.dest_buf = args.buf; @@ -1324,9 +1324,7 @@ u32 vidtv_psi_sdt_write_into(struct vidtv_psi_sdt_write_args args) u32 crc = INITIAL_CRC; struct vidtv_psi_table_sdt_service *service = args.sdt->service; - struct vidtv_psi_desc *service_desc = (args.sdt->service) ? - args.sdt->service->descriptor : - NULL; + struct vidtv_psi_desc *service_desc; struct header_write_args h_args = {}; struct psi_write_args psi_args = {}; @@ -1373,6 +1371,8 @@ u32 vidtv_psi_sdt_write_into(struct vidtv_psi_sdt_write_args args) nbytes += vidtv_psi_ts_psi_write_into(psi_args); + service_desc = service->descriptor; + while (service_desc) { /* copy the service descriptors, if any */ d_args.dest_buf = args.buf; @@ -1616,9 +1616,7 @@ u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args args) struct vidtv_psi_desc *table_descriptor = args.nit->descriptor; struct vidtv_psi_table_transport *transport = args.nit->transport; - struct vidtv_psi_desc *transport_descriptor = (transport) ? - args.nit->transport->descriptor : - NULL; + struct vidtv_psi_desc *transport_descriptor; struct header_write_args h_args = {}; struct psi_write_args psi_args = {}; @@ -1686,6 +1684,8 @@ u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args args) nbytes += vidtv_psi_ts_psi_write_into(psi_args); + transport_descriptor = transport->descriptor; + while (transport_descriptor) { /* write the transport descriptors, if any */ d_args.dest_buf = args.buf; @@ -1823,9 +1823,7 @@ u32 vidtv_psi_eit_write_into(struct vidtv_psi_eit_write_args args) u32 crc = INITIAL_CRC; struct vidtv_psi_table_eit_event *event = args.eit->event; - struct vidtv_psi_desc *event_descriptor = (args.eit->event) ? - args.eit->event->descriptor : - NULL; + struct vidtv_psi_desc *event_descriptor; struct header_write_args h_args = {}; struct psi_write_args psi_args = {}; -- cgit v1.2.3 From 8922e3931dd79055bb3f851bed33f069fc67a2fc Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 21 Sep 2020 14:19:08 +0200 Subject: media: vidtv: reorganize includes - Place the includes on alphabetical order; - get rid of asm/byteorder.h; - add bug.h at vidtv_s302m.c, as it is needed by inux/fixp-arith.h Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_bridge.c | 8 ++++---- drivers/media/test-drivers/vidtv/vidtv_bridge.h | 2 ++ drivers/media/test-drivers/vidtv/vidtv_channel.c | 8 ++++---- drivers/media/test-drivers/vidtv/vidtv_channel.h | 3 ++- drivers/media/test-drivers/vidtv/vidtv_demod.c | 1 + drivers/media/test-drivers/vidtv/vidtv_demod.h | 1 + drivers/media/test-drivers/vidtv/vidtv_mux.c | 18 +++++++++--------- drivers/media/test-drivers/vidtv/vidtv_mux.h | 3 ++- drivers/media/test-drivers/vidtv/vidtv_pes.c | 1 - drivers/media/test-drivers/vidtv/vidtv_pes.h | 1 - drivers/media/test-drivers/vidtv/vidtv_psi.c | 11 +++++------ drivers/media/test-drivers/vidtv/vidtv_psi.h | 1 - drivers/media/test-drivers/vidtv/vidtv_s302m.c | 21 ++++++++++----------- drivers/media/test-drivers/vidtv/vidtv_s302m.h | 1 - drivers/media/test-drivers/vidtv/vidtv_ts.c | 5 ++--- drivers/media/test-drivers/vidtv/vidtv_ts.h | 1 - drivers/media/test-drivers/vidtv/vidtv_tuner.c | 5 +++-- drivers/media/test-drivers/vidtv/vidtv_tuner.h | 1 + 18 files changed, 46 insertions(+), 46 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_bridge.c b/drivers/media/test-drivers/vidtv/vidtv_bridge.c index 2f97ecf423ed..068fb4e9fafe 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_bridge.c +++ b/drivers/media/test-drivers/vidtv/vidtv_bridge.c @@ -9,20 +9,20 @@ * Copyright (C) 2020 Daniel W. S. Almeida */ +#include #include #include #include -#include #include #include #include #include "vidtv_bridge.h" +#include "vidtv_common.h" #include "vidtv_demod.h" -#include "vidtv_tuner.h" -#include "vidtv_ts.h" #include "vidtv_mux.h" -#include "vidtv_common.h" +#include "vidtv_ts.h" +#include "vidtv_tuner.h" //#define MUX_BUF_MAX_SZ //#define MUX_BUF_MIN_SZ diff --git a/drivers/media/test-drivers/vidtv/vidtv_bridge.h b/drivers/media/test-drivers/vidtv/vidtv_bridge.h index 78fe8472fa37..a85068bffd0f 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_bridge.h +++ b/drivers/media/test-drivers/vidtv/vidtv_bridge.h @@ -20,9 +20,11 @@ #include #include #include + #include #include #include + #include "vidtv_mux.h" /** diff --git a/drivers/media/test-drivers/vidtv/vidtv_channel.c b/drivers/media/test-drivers/vidtv/vidtv_channel.c index 13e56544bb1e..683da9014064 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_channel.c +++ b/drivers/media/test-drivers/vidtv/vidtv_channel.c @@ -19,16 +19,16 @@ * Copyright (C) 2020 Daniel W. S. Almeida */ -#include -#include #include #include +#include +#include #include "vidtv_channel.h" -#include "vidtv_psi.h" +#include "vidtv_common.h" #include "vidtv_encoder.h" #include "vidtv_mux.h" -#include "vidtv_common.h" +#include "vidtv_psi.h" #include "vidtv_s302m.h" static void vidtv_channel_encoder_destroy(struct vidtv_encoder *e) diff --git a/drivers/media/test-drivers/vidtv/vidtv_channel.h b/drivers/media/test-drivers/vidtv/vidtv_channel.h index 40ed7fcdc5a1..e1ba638ab77f 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_channel.h +++ b/drivers/media/test-drivers/vidtv/vidtv_channel.h @@ -23,9 +23,10 @@ #define VIDTV_CHANNEL_H #include -#include "vidtv_psi.h" + #include "vidtv_encoder.h" #include "vidtv_mux.h" +#include "vidtv_psi.h" /** * struct vidtv_channel - A 'channel' abstraction diff --git a/drivers/media/test-drivers/vidtv/vidtv_demod.c b/drivers/media/test-drivers/vidtv/vidtv_demod.c index eba7fe1a1b48..63ac55b81f39 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_demod.c +++ b/drivers/media/test-drivers/vidtv/vidtv_demod.c @@ -19,6 +19,7 @@ #include #include #include + #include #include "vidtv_demod.h" diff --git a/drivers/media/test-drivers/vidtv/vidtv_demod.h b/drivers/media/test-drivers/vidtv/vidtv_demod.h index 87651b0193e6..ab84044f33ba 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_demod.h +++ b/drivers/media/test-drivers/vidtv/vidtv_demod.h @@ -12,6 +12,7 @@ #define VIDTV_DEMOD_H #include + #include /** diff --git a/drivers/media/test-drivers/vidtv/vidtv_mux.c b/drivers/media/test-drivers/vidtv/vidtv_mux.c index c3646dd269dd..465c5a6a3bc8 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_mux.c +++ b/drivers/media/test-drivers/vidtv/vidtv_mux.c @@ -12,23 +12,23 @@ * Copyright (C) 2020 Daniel W. S. Almeida */ -#include -#include +#include +#include #include #include -#include +#include #include -#include +#include +#include #include -#include -#include "vidtv_mux.h" -#include "vidtv_ts.h" -#include "vidtv_pes.h" -#include "vidtv_encoder.h" #include "vidtv_channel.h" #include "vidtv_common.h" +#include "vidtv_encoder.h" +#include "vidtv_mux.h" +#include "vidtv_pes.h" #include "vidtv_psi.h" +#include "vidtv_ts.h" static struct vidtv_mux_pid_ctx *vidtv_mux_get_pid_ctx(struct vidtv_mux *m, u16 pid) diff --git a/drivers/media/test-drivers/vidtv/vidtv_mux.h b/drivers/media/test-drivers/vidtv/vidtv_mux.h index 6eeb09fbfe4d..005b707f1445 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_mux.h +++ b/drivers/media/test-drivers/vidtv/vidtv_mux.h @@ -15,9 +15,10 @@ #ifndef VIDTV_MUX_H #define VIDTV_MUX_H -#include #include +#include #include + #include #include "vidtv_psi.h" diff --git a/drivers/media/test-drivers/vidtv/vidtv_pes.c b/drivers/media/test-drivers/vidtv/vidtv_pes.c index 1c75f88070e9..102352d398ed 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_pes.c +++ b/drivers/media/test-drivers/vidtv/vidtv_pes.c @@ -16,7 +16,6 @@ #include #include #include -#include #include "vidtv_pes.h" #include "vidtv_common.h" diff --git a/drivers/media/test-drivers/vidtv/vidtv_pes.h b/drivers/media/test-drivers/vidtv/vidtv_pes.h index 0ea9e863024d..a152693233a9 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_pes.h +++ b/drivers/media/test-drivers/vidtv/vidtv_pes.h @@ -14,7 +14,6 @@ #ifndef VIDTV_PES_H #define VIDTV_PES_H -#include #include #include "vidtv_common.h" diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c index 4dda5b0004a3..f4f6b90633db 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.c +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c @@ -11,18 +11,17 @@ #define pr_fmt(fmt) KBUILD_MODNAME ":%s, %d: " fmt, __func__, __LINE__ -#include -#include -#include #include -#include +#include #include #include +#include +#include #include -#include +#include -#include "vidtv_psi.h" #include "vidtv_common.h" +#include "vidtv_psi.h" #include "vidtv_ts.h" #define CRC_SIZE_IN_BYTES 4 diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.h b/drivers/media/test-drivers/vidtv/vidtv_psi.h index 58efe54f7a5a..4fcb2c0615bb 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.h +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.h @@ -13,7 +13,6 @@ #define VIDTV_PSI_H #include -#include /* * all section lengths start immediately after the 'section_length' field diff --git a/drivers/media/test-drivers/vidtv/vidtv_s302m.c b/drivers/media/test-drivers/vidtv/vidtv_s302m.c index aacf8110d874..ec88af63a74e 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_s302m.c +++ b/drivers/media/test-drivers/vidtv/vidtv_s302m.c @@ -17,23 +17,22 @@ #define pr_fmt(fmt) KBUILD_MODNAME ":%s, %d: " fmt, __func__, __LINE__ -#include -#include +#include #include -#include -#include -#include +#include #include +#include +#include #include #include -#include - -#include -#include +#include +#include +#include +#include -#include "vidtv_s302m.h" -#include "vidtv_encoder.h" #include "vidtv_common.h" +#include "vidtv_encoder.h" +#include "vidtv_s302m.h" #define S302M_SAMPLING_RATE_HZ 48000 #define PES_PRIVATE_STREAM_1 0xbd /* PES: private_stream_1 */ diff --git a/drivers/media/test-drivers/vidtv/vidtv_s302m.h b/drivers/media/test-drivers/vidtv/vidtv_s302m.h index b1bbe521e766..a0101734e758 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_s302m.h +++ b/drivers/media/test-drivers/vidtv/vidtv_s302m.h @@ -19,7 +19,6 @@ #define VIDTV_S302M_H #include -#include #include "vidtv_encoder.h" diff --git a/drivers/media/test-drivers/vidtv/vidtv_ts.c b/drivers/media/test-drivers/vidtv/vidtv_ts.c index 190b9e4438dc..ca4bb9c40b78 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_ts.c +++ b/drivers/media/test-drivers/vidtv/vidtv_ts.c @@ -9,14 +9,13 @@ #define pr_fmt(fmt) KBUILD_MODNAME ":%s, %d: " fmt, __func__, __LINE__ +#include #include #include #include -#include -#include -#include "vidtv_ts.h" #include "vidtv_common.h" +#include "vidtv_ts.h" static u32 vidtv_ts_write_pcr_bits(u8 *to, u32 to_offset, u64 pcr) { diff --git a/drivers/media/test-drivers/vidtv/vidtv_ts.h b/drivers/media/test-drivers/vidtv/vidtv_ts.h index 83dcc9183b45..6b989a2c1433 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_ts.h +++ b/drivers/media/test-drivers/vidtv/vidtv_ts.h @@ -11,7 +11,6 @@ #define VIDTV_TS_H #include -#include #define TS_SYNC_BYTE 0x47 #define TS_PACKET_LEN 188 diff --git a/drivers/media/test-drivers/vidtv/vidtv_tuner.c b/drivers/media/test-drivers/vidtv/vidtv_tuner.c index 9bc49e099f65..14b6bc902ee1 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_tuner.c +++ b/drivers/media/test-drivers/vidtv/vidtv_tuner.c @@ -13,11 +13,12 @@ #include #include #include +#include +#include #include #include + #include -#include -#include #include "vidtv_tuner.h" diff --git a/drivers/media/test-drivers/vidtv/vidtv_tuner.h b/drivers/media/test-drivers/vidtv/vidtv_tuner.h index 8455b2d564b3..fd55346a5c87 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_tuner.h +++ b/drivers/media/test-drivers/vidtv/vidtv_tuner.h @@ -11,6 +11,7 @@ #define VIDTV_TUNER_H #include + #include #define NUM_VALID_TUNER_FREQS 8 -- cgit v1.2.3 From 3be8037960bccd13052cfdeba8805ad785041d70 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 21 Sep 2020 15:11:50 +0200 Subject: media: vidtv: add error checks Currently, there are not checks if something gets bad during memory allocation: it will simply use NULL pointers and crash. Add error path at the logic which allocates memory for the MPEG-TS generator code, propagating the errors up to the vidtv_bridge. Now, if something wents bad, start_streaming will return an error that userspace can detect: ERROR DMX_SET_PES_FILTER failed (PID = 0x2000): 12 Cannot allocate memory and the driver doesn't crash. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_bridge.c | 2 + drivers/media/test-drivers/vidtv/vidtv_channel.c | 137 ++++++++++++++++++++--- drivers/media/test-drivers/vidtv/vidtv_channel.h | 4 +- drivers/media/test-drivers/vidtv/vidtv_mux.c | 85 +++++++++----- drivers/media/test-drivers/vidtv/vidtv_psi.c | 109 ++++++++++++++---- drivers/media/test-drivers/vidtv/vidtv_s302m.c | 19 +++- 6 files changed, 289 insertions(+), 67 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_bridge.c b/drivers/media/test-drivers/vidtv/vidtv_bridge.c index 068fb4e9fafe..e846aaab2c44 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_bridge.c +++ b/drivers/media/test-drivers/vidtv/vidtv_bridge.c @@ -185,6 +185,8 @@ static int vidtv_start_streaming(struct vidtv_dvb *dvb) dvb->streaming = true; dvb->mux = vidtv_mux_init(dvb->fe[0], dev, mux_args); + if (!dvb->mux) + return -ENOMEM; vidtv_mux_start_thread(dvb->mux); dev_dbg_ratelimited(dev, "Started streaming\n"); diff --git a/drivers/media/test-drivers/vidtv/vidtv_channel.c b/drivers/media/test-drivers/vidtv/vidtv_channel.c index 683da9014064..ddfeecd381e6 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_channel.c +++ b/drivers/media/test-drivers/vidtv/vidtv_channel.c @@ -57,54 +57,75 @@ struct vidtv_channel const u16 s302m_program_pid = 0x101; /* packet id for PMT*/ const u16 s302m_es_pid = 0x111; /* packet id for the ES */ const __be32 s302m_fid = cpu_to_be32(VIDTV_S302M_FORMAT_IDENTIFIER); - char *name = ENCODING_ISO8859_15 "Beethoven"; char *provider = ENCODING_ISO8859_15 "LinuxTV.org"; char *iso_language_code = ENCODING_ISO8859_15 "eng"; char *event_name = ENCODING_ISO8859_15 "Beethoven Music"; char *event_text = ENCODING_ISO8859_15 "Beethoven's 5th Symphony"; const u16 s302m_beethoven_event_id = 1; - - struct vidtv_channel *s302m = kzalloc(sizeof(*s302m), GFP_KERNEL); + struct vidtv_channel *s302m; struct vidtv_s302m_encoder_init_args encoder_args = {}; + s302m = kzalloc(sizeof(*s302m), GFP_KERNEL); + if (!s302m) + return NULL; + s302m->name = kstrdup(name, GFP_KERNEL); + if (!s302m->name) + goto free_s302m; s302m->service = vidtv_psi_sdt_service_init(NULL, s302m_service_id, false, true); + if (!s302m->service) + goto free_name; s302m->service->descriptor = (struct vidtv_psi_desc *) vidtv_psi_service_desc_init(NULL, DIGITAL_TELEVISION_SERVICE, name, provider); + if (!s302m->service->descriptor) + goto free_service; s302m->transport_stream_id = transport_stream_id; s302m->program = vidtv_psi_pat_program_init(NULL, s302m_service_id, s302m_program_pid); + if (!s302m->program) + goto free_service; s302m->program_num = s302m_program_num; s302m->streams = vidtv_psi_pmt_stream_init(NULL, STREAM_PRIVATE_DATA, s302m_es_pid); + if (!s302m->streams) + goto free_program; s302m->streams->descriptor = (struct vidtv_psi_desc *) vidtv_psi_registration_desc_init(NULL, s302m_fid, NULL, 0); + if (!s302m->streams->descriptor) + goto free_streams; + encoder_args.es_pid = s302m_es_pid; s302m->encoders = vidtv_s302m_encoder_init(encoder_args); + if (!s302m->encoders) + goto free_streams; s302m->events = vidtv_psi_eit_event_init(NULL, s302m_beethoven_event_id); + if (!s302m->events) + goto free_encoders; s302m->events->descriptor = (struct vidtv_psi_desc *) vidtv_psi_short_event_desc_init(NULL, iso_language_code, event_name, event_text); + if (!s302m->events->descriptor) + goto free_events; if (head) { while (head->next) @@ -114,6 +135,23 @@ struct vidtv_channel } return s302m; + +free_events: + vidtv_psi_eit_event_destroy(s302m->events); +free_encoders: + vidtv_s302m_encoder_destroy(s302m->encoders); +free_streams: + vidtv_psi_pmt_stream_destroy(s302m->streams); +free_program: + vidtv_psi_pat_program_destroy(s302m->program); +free_service: + vidtv_psi_sdt_service_destroy(s302m->service); +free_name: + kfree(s302m->name); +free_s302m: + kfree(s302m); + + return NULL; } static struct vidtv_psi_table_eit_event @@ -142,6 +180,10 @@ static struct vidtv_psi_table_eit_event while (curr) { event_id = be16_to_cpu(curr->event_id); tail = vidtv_psi_eit_event_init(tail, event_id); + if (!tail) { + vidtv_psi_eit_event_destroy(head); + return NULL; + } desc = vidtv_psi_desc_clone(curr->descriptor); vidtv_psi_desc_assign(&tail->descriptor, desc); @@ -187,8 +229,12 @@ static struct vidtv_psi_table_sdt_service service_id, curr->EIT_schedule, curr->EIT_present_following); + if (!tail) + goto free; desc = vidtv_psi_desc_clone(curr->descriptor); + if (!desc) + goto free_tail; vidtv_psi_desc_assign(&tail->descriptor, desc); if (!head) @@ -201,6 +247,12 @@ static struct vidtv_psi_table_sdt_service } return head; + +free_tail: + vidtv_psi_sdt_service_destroy(tail); +free: + vidtv_psi_sdt_service_destroy(head); + return NULL; } static struct vidtv_psi_table_pat_program* @@ -231,6 +283,10 @@ vidtv_channel_pat_prog_cat_into_new(struct vidtv_mux *m) tail = vidtv_psi_pat_program_init(tail, serv_id, pid); + if (!tail) { + vidtv_psi_pat_program_destroy(head); + return NULL; + } if (!head) head = tail; @@ -303,6 +359,17 @@ vidtv_channel_pmt_match_sections(struct vidtv_channel *channels, } } +static void vidtv_channel_destroy_service_list(struct vidtv_psi_desc_service_list_entry *e) +{ + struct vidtv_psi_desc_service_list_entry *tmp; + + while (e) { + tmp = e; + e = e->next; + kfree(tmp); + } +} + static struct vidtv_psi_desc_service_list_entry *vidtv_channel_build_service_list(struct vidtv_psi_table_sdt_service *s) { @@ -320,6 +387,11 @@ static struct vidtv_psi_desc_service_list_entry s_desc = (struct vidtv_psi_desc_service *)desc; curr_e = kzalloc(sizeof(*curr_e), GFP_KERNEL); + if (!curr_e) { + vidtv_channel_destroy_service_list(head_e); + return NULL; + } + curr_e->service_id = s->service_id; curr_e->service_type = s_desc->service_type; @@ -338,18 +410,7 @@ next_desc: return head_e; } -static void vidtv_channel_destroy_service_list(struct vidtv_psi_desc_service_list_entry *e) -{ - struct vidtv_psi_desc_service_list_entry *tmp; - - while (e) { - tmp = e; - e = e->next; - kfree(tmp); - } -} - -void vidtv_channel_si_init(struct vidtv_mux *m) +int vidtv_channel_si_init(struct vidtv_mux *m) { struct vidtv_psi_table_pat_program *programs = NULL; struct vidtv_psi_table_sdt_service *services = NULL; @@ -357,24 +418,41 @@ void vidtv_channel_si_init(struct vidtv_mux *m) struct vidtv_psi_table_eit_event *events = NULL; m->si.pat = vidtv_psi_pat_table_init(m->transport_stream_id); + if (!m->si.pat) + return -ENOMEM; m->si.sdt = vidtv_psi_sdt_table_init(m->transport_stream_id); + if (!m->si.sdt) + goto free_pat; programs = vidtv_channel_pat_prog_cat_into_new(m); + if (!programs) + goto free_sdt; services = vidtv_channel_sdt_serv_cat_into_new(m); + if (!services) + goto free_programs; events = vidtv_channel_eit_event_cat_into_new(m); + if (!events) + goto free_services; /* look for a service descriptor for every service */ service_list = vidtv_channel_build_service_list(services); + if (!service_list) + goto free_events; /* use these descriptors to build the NIT */ m->si.nit = vidtv_psi_nit_table_init(m->network_id, m->transport_stream_id, m->network_name, service_list); + if (!m->si.nit) + goto free_service_list; m->si.eit = vidtv_psi_eit_table_init(m->network_id, m->transport_stream_id); + if (!m->si.eit) + goto free_nit; + /* assemble all programs and assign to PAT */ vidtv_psi_pat_program_assign(m->si.pat, programs); @@ -386,12 +464,34 @@ void vidtv_channel_si_init(struct vidtv_mux *m) vidtv_psi_eit_event_assign(m->si.eit, events); m->si.pmt_secs = vidtv_psi_pmt_create_sec_for_each_pat_entry(m->si.pat, m->pcr_pid); + if (!m->si.pmt_secs) + goto free_eit; vidtv_channel_pmt_match_sections(m->channels, m->si.pmt_secs, m->si.pat->programs); vidtv_channel_destroy_service_list(service_list); + + return 0; + +free_eit: + vidtv_psi_eit_table_destroy(m->si.eit); +free_nit: + vidtv_psi_nit_table_destroy(m->si.nit); +free_service_list: + vidtv_channel_destroy_service_list(service_list); +free_events: + vidtv_psi_eit_event_destroy(events); +free_services: + vidtv_psi_sdt_service_destroy(services); +free_programs: + vidtv_psi_pat_program_destroy(programs); +free_sdt: + vidtv_psi_sdt_table_destroy(m->si.sdt); +free_pat: + vidtv_psi_pat_table_destroy(m->si.pat); + return 0; } void vidtv_channel_si_destroy(struct vidtv_mux *m) @@ -410,10 +510,15 @@ void vidtv_channel_si_destroy(struct vidtv_mux *m) vidtv_psi_eit_table_destroy(m->si.eit); } -void vidtv_channels_init(struct vidtv_mux *m) +int vidtv_channels_init(struct vidtv_mux *m) { /* this is the place to add new 'channels' for vidtv */ m->channels = vidtv_channel_s302m_init(NULL, m->transport_stream_id); + + if (!m->channels) + return -ENOMEM; + + return 0; } void vidtv_channels_destroy(struct vidtv_mux *m) diff --git a/drivers/media/test-drivers/vidtv/vidtv_channel.h b/drivers/media/test-drivers/vidtv/vidtv_channel.h index e1ba638ab77f..4bc2a4c0980d 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_channel.h +++ b/drivers/media/test-drivers/vidtv/vidtv_channel.h @@ -65,14 +65,14 @@ struct vidtv_channel { * vidtv_channel_si_init - Init the PSI tables from the channels in the mux * @m: The mux containing the channels. */ -void vidtv_channel_si_init(struct vidtv_mux *m); +int vidtv_channel_si_init(struct vidtv_mux *m); void vidtv_channel_si_destroy(struct vidtv_mux *m); /** * vidtv_channels_init - Init hardcoded, fake 'channels'. * @m: The mux to store the channels into. */ -void vidtv_channels_init(struct vidtv_mux *m); +int vidtv_channels_init(struct vidtv_mux *m); struct vidtv_channel *vidtv_channel_s302m_init(struct vidtv_channel *head, u16 transport_stream_id); void vidtv_channels_destroy(struct vidtv_mux *m); diff --git a/drivers/media/test-drivers/vidtv/vidtv_mux.c b/drivers/media/test-drivers/vidtv/vidtv_mux.c index 465c5a6a3bc8..bba3f2315531 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_mux.c +++ b/drivers/media/test-drivers/vidtv/vidtv_mux.c @@ -47,37 +47,56 @@ static struct vidtv_mux_pid_ctx struct vidtv_mux_pid_ctx *ctx; ctx = vidtv_mux_get_pid_ctx(m, pid); - if (ctx) - goto end; + return ctx; + + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return NULL; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); ctx->pid = pid; ctx->cc = 0; hash_add(m->pid_ctx, &ctx->h, pid); -end: return ctx; } -static void vidtv_mux_pid_ctx_init(struct vidtv_mux *m) +static void vidtv_mux_pid_ctx_destroy(struct vidtv_mux *m) +{ + int bkt; + struct vidtv_mux_pid_ctx *ctx; + struct hlist_node *tmp; + + hash_for_each_safe(m->pid_ctx, bkt, tmp, ctx, h) { + hash_del(&ctx->h); + kfree(ctx); + } +} + +static int vidtv_mux_pid_ctx_init(struct vidtv_mux *m) { struct vidtv_psi_table_pat_program *p = m->si.pat->program; u16 pid; hash_init(m->pid_ctx); /* push the pcr pid ctx */ - vidtv_mux_create_pid_ctx_once(m, m->pcr_pid); - /* push the null packet pid ctx */ - vidtv_mux_create_pid_ctx_once(m, TS_NULL_PACKET_PID); + if (!vidtv_mux_create_pid_ctx_once(m, m->pcr_pid)) + return -ENOMEM; + /* push the NULL packet pid ctx */ + if (!vidtv_mux_create_pid_ctx_once(m, TS_NULL_PACKET_PID)) + goto free; /* push the PAT pid ctx */ - vidtv_mux_create_pid_ctx_once(m, VIDTV_PAT_PID); + if (!vidtv_mux_create_pid_ctx_once(m, VIDTV_PAT_PID)) + goto free; /* push the SDT pid ctx */ - vidtv_mux_create_pid_ctx_once(m, VIDTV_SDT_PID); + if (!vidtv_mux_create_pid_ctx_once(m, VIDTV_SDT_PID)) + goto free; /* push the NIT pid ctx */ - vidtv_mux_create_pid_ctx_once(m, VIDTV_NIT_PID); + if (!vidtv_mux_create_pid_ctx_once(m, VIDTV_NIT_PID)) + goto free; /* push the EIT pid ctx */ - vidtv_mux_create_pid_ctx_once(m, VIDTV_EIT_PID); + if (!vidtv_mux_create_pid_ctx_once(m, VIDTV_EIT_PID)) + goto free; /* add a ctx for all PMT sections */ while (p) { @@ -85,18 +104,12 @@ static void vidtv_mux_pid_ctx_init(struct vidtv_mux *m) vidtv_mux_create_pid_ctx_once(m, pid); p = p->next; } -} -static void vidtv_mux_pid_ctx_destroy(struct vidtv_mux *m) -{ - int bkt; - struct vidtv_mux_pid_ctx *ctx; - struct hlist_node *tmp; + return 0; - hash_for_each_safe(m->pid_ctx, bkt, tmp, ctx, h) { - hash_del(&ctx->h); - kfree(ctx); - } +free: + vidtv_mux_pid_ctx_destroy(m); + return -ENOMEM; } static void vidtv_mux_update_clk(struct vidtv_mux *m) @@ -455,7 +468,11 @@ struct vidtv_mux *vidtv_mux_init(struct dvb_frontend *fe, struct device *dev, struct vidtv_mux_init_args args) { - struct vidtv_mux *m = kzalloc(sizeof(*m), GFP_KERNEL); + struct vidtv_mux *m; + + m = kzalloc(sizeof(*m), GFP_KERNEL); + if (!m) + return NULL; m->dev = dev; m->fe = fe; @@ -467,6 +484,9 @@ struct vidtv_mux *vidtv_mux_init(struct dvb_frontend *fe, m->on_new_packets_available_cb = args.on_new_packets_available_cb; m->mux_buf = vzalloc(args.mux_buf_sz); + if (!m->mux_buf) + goto free_mux; + m->mux_buf_sz = args.mux_buf_sz; m->pcr_pid = args.pcr_pid; @@ -479,16 +499,29 @@ struct vidtv_mux *vidtv_mux_init(struct dvb_frontend *fe, if (args.channels) m->channels = args.channels; else - vidtv_channels_init(m); + if (vidtv_channels_init(m) < 0) + goto free_mux_buf; /* will alloc data for pmt_sections after initializing pat */ - vidtv_channel_si_init(m); + if (vidtv_channel_si_init(m) < 0) + goto free_channels; INIT_WORK(&m->mpeg_thread, vidtv_mux_tick); - vidtv_mux_pid_ctx_init(m); + if (vidtv_mux_pid_ctx_init(m) < 0) + goto free_channel_si; return m; + +free_channel_si: + vidtv_channel_si_destroy(m); +free_channels: + vidtv_channels_destroy(m); +free_mux_buf: + vfree(m->mux_buf); +free_mux: + kfree(m); + return NULL; } void vidtv_mux_destroy(struct vidtv_mux *m) diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c index f4f6b90633db..f7caa96c0ee8 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.c +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c @@ -333,6 +333,8 @@ struct vidtv_psi_desc_service *vidtv_psi_service_desc_init(struct vidtv_psi_desc u32 provider_name_len = provider_name ? strlen(provider_name) : 0; desc = kzalloc(sizeof(*desc), GFP_KERNEL); + if (!desc) + return NULL; desc->type = SERVICE_DESCRIPTOR; @@ -367,6 +369,8 @@ struct vidtv_psi_desc_registration struct vidtv_psi_desc_registration *desc; desc = kzalloc(sizeof(*desc) + sizeof(format_id) + additional_info_len, GFP_KERNEL); + if (!desc) + return NULL; desc->type = REGISTRATION_DESCRIPTOR; @@ -391,6 +395,8 @@ struct vidtv_psi_desc_network_name u32 network_name_len = network_name ? strlen(network_name) : 0; desc = kzalloc(sizeof(*desc), GFP_KERNEL); + if (!desc) + return NULL; desc->type = NETWORK_NAME_DESCRIPTOR; @@ -414,11 +420,23 @@ struct vidtv_psi_desc_service_list u16 length = 0; desc = kzalloc(sizeof(*desc), GFP_KERNEL); + if (!desc) + return NULL; desc->type = SERVICE_LIST_DESCRIPTOR; while (entry) { curr_e = kzalloc(sizeof(*curr_e), GFP_KERNEL); + if (!curr_e) { + while (head_e) { + curr_e = head_e; + head_e = head_e->next; + kfree(curr_e); + } + kfree(desc); + return NULL; + } + curr_e->service_id = entry->service_id; curr_e->service_type = entry->service_type; @@ -453,6 +471,8 @@ struct vidtv_psi_desc_short_event u32 iso_len = iso_language_code ? strlen(iso_language_code) : 0; desc = kzalloc(sizeof(*desc), GFP_KERNEL); + if (!desc) + return NULL; desc->type = SHORT_EVENT_DESCRIPTOR; @@ -496,10 +516,10 @@ struct vidtv_psi_desc *vidtv_psi_desc_clone(struct vidtv_psi_desc *desc) case SERVICE_DESCRIPTOR: service = (struct vidtv_psi_desc_service *)desc; curr = (struct vidtv_psi_desc *) - vidtv_psi_service_desc_init(head, - service->service_type, - service->service_name, - service->provider_name); + vidtv_psi_service_desc_init(head, + service->service_type, + service->service_name, + service->provider_name); break; case NETWORK_NAME_DESCRIPTOR: @@ -512,8 +532,8 @@ struct vidtv_psi_desc *vidtv_psi_desc_clone(struct vidtv_psi_desc *desc) case SERVICE_LIST_DESCRIPTOR: desc_service_list = (struct vidtv_psi_desc_service_list *)desc; curr = (struct vidtv_psi_desc *) - vidtv_psi_service_list_desc_init(head, - desc_service_list->service_list); + vidtv_psi_service_list_desc_init(head, + desc_service_list->service_list); break; case SHORT_EVENT_DESCRIPTOR: @@ -528,12 +548,15 @@ struct vidtv_psi_desc *vidtv_psi_desc_clone(struct vidtv_psi_desc *desc) case REGISTRATION_DESCRIPTOR: default: curr = kzalloc(sizeof(*desc) + desc->length, GFP_KERNEL); + if (!curr) + return NULL; memcpy(curr, desc, sizeof(*desc) + desc->length); - break; - } + } + + if (!curr) + return NULL; - if (curr) - curr->next = NULL; + curr->next = NULL; if (!head) head = curr; if (prev) @@ -890,6 +913,8 @@ vidtv_psi_pat_program_init(struct vidtv_psi_table_pat_program *head, const u16 RESERVED = 0x07; program = kzalloc(sizeof(*program), GFP_KERNEL); + if (!program) + return NULL; program->service_id = cpu_to_be16(service_id); @@ -951,11 +976,15 @@ vidtv_psi_pat_program_assign(struct vidtv_psi_table_pat *pat, struct vidtv_psi_table_pat *vidtv_psi_pat_table_init(u16 transport_stream_id) { - struct vidtv_psi_table_pat *pat = kzalloc(sizeof(*pat), GFP_KERNEL); + struct vidtv_psi_table_pat *pat; const u16 SYNTAX = 0x1; const u16 ZERO = 0x0; const u16 ONES = 0x03; + pat = kzalloc(sizeof(*pat), GFP_KERNEL); + if (!pat) + return NULL; + pat->header.table_id = 0x0; pat->header.bitfield = cpu_to_be16((SYNTAX << 15) | (ZERO << 14) | (ONES << 12)); @@ -1055,6 +1084,8 @@ vidtv_psi_pmt_stream_init(struct vidtv_psi_table_pmt_stream *head, u16 desc_loop_len; stream = kzalloc(sizeof(*stream), GFP_KERNEL); + if (!stream) + return NULL; stream->type = stream_type; @@ -1129,7 +1160,7 @@ u16 vidtv_psi_pmt_get_pid(struct vidtv_psi_table_pmt *section, struct vidtv_psi_table_pmt *vidtv_psi_pmt_table_init(u16 program_number, u16 pcr_pid) { - struct vidtv_psi_table_pmt *pmt = kzalloc(sizeof(*pmt), GFP_KERNEL); + struct vidtv_psi_table_pmt *pmt; const u16 SYNTAX = 0x1; const u16 ZERO = 0x0; const u16 ONES = 0x03; @@ -1137,6 +1168,10 @@ struct vidtv_psi_table_pmt *vidtv_psi_pmt_table_init(u16 program_number, const u16 RESERVED2 = 0x0f; u16 desc_loop_len; + pmt = kzalloc(sizeof(*pmt), GFP_KERNEL); + if (!pmt) + return NULL; + if (!pcr_pid) pcr_pid = 0x1fff; @@ -1276,14 +1311,17 @@ void vidtv_psi_pmt_table_destroy(struct vidtv_psi_table_pmt *pmt) struct vidtv_psi_table_sdt *vidtv_psi_sdt_table_init(u16 transport_stream_id) { - struct vidtv_psi_table_sdt *sdt = kzalloc(sizeof(*sdt), GFP_KERNEL); + struct vidtv_psi_table_sdt *sdt; const u16 SYNTAX = 0x1; const u16 ONE = 0x1; const u16 ONES = 0x03; const u16 RESERVED = 0xff; - sdt->header.table_id = 0x42; + sdt = kzalloc(sizeof(*sdt), GFP_KERNEL); + if (!sdt) + return NULL; + sdt->header.table_id = 0x42; sdt->header.bitfield = cpu_to_be16((SYNTAX << 15) | (ONE << 14) | (ONES << 12)); /* @@ -1418,6 +1456,8 @@ struct vidtv_psi_table_sdt_service struct vidtv_psi_table_sdt_service *service; service = kzalloc(sizeof(*service), GFP_KERNEL); + if (!service) + return NULL; /* * ETSI 300 468: this is a 16bit field which serves as a label to @@ -1491,6 +1531,8 @@ vidtv_psi_pmt_create_sec_for_each_pat_entry(struct vidtv_psi_table_pat *pat, u16 pmt_secs = kcalloc(pat->programs, 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); @@ -1568,13 +1610,20 @@ struct vidtv_psi_table_nit char *network_name, struct vidtv_psi_desc_service_list_entry *service_list) { - struct vidtv_psi_table_nit *nit = kzalloc(sizeof(*nit), GFP_KERNEL); - struct vidtv_psi_table_transport *transport = kzalloc(sizeof(*transport), GFP_KERNEL); - + struct vidtv_psi_table_nit *nit; + struct vidtv_psi_table_transport *transport; const u16 SYNTAX = 0x1; const u16 ONE = 0x1; const u16 ONES = 0x03; + nit = kzalloc(sizeof(*nit), GFP_KERNEL); + if (!nit) + return NULL; + + transport = kzalloc(sizeof(*transport), GFP_KERNEL); + if (!transport) + goto free_nit; + nit->header.table_id = 0x40; // ACTUAL_NETWORK nit->header.bitfield = cpu_to_be16((SYNTAX << 15) | (ONE << 14) | (ONES << 12)); @@ -1593,18 +1642,31 @@ struct vidtv_psi_table_nit nit->descriptor = (struct vidtv_psi_desc *) vidtv_psi_network_name_desc_init(NULL, network_name); + if (!nit->descriptor) + goto free_transport; transport->transport_id = cpu_to_be16(transport_stream_id); transport->network_id = cpu_to_be16(network_id); transport->bitfield = cpu_to_be16(0xf); transport->descriptor = (struct vidtv_psi_desc *) vidtv_psi_service_list_desc_init(NULL, service_list); + if (!transport->descriptor) + goto free_nit_desc; nit->transport = transport; vidtv_psi_nit_table_update_sec_len(nit); return nit; + +free_nit_desc: + vidtv_psi_desc_destroy((struct vidtv_psi_desc *)nit->descriptor); + +free_transport: + kfree(transport); +free_nit: + kfree(nit); + return NULL; } u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args args) @@ -1786,12 +1848,15 @@ struct vidtv_psi_table_eit *vidtv_psi_eit_table_init(u16 network_id, u16 transport_stream_id) { - struct vidtv_psi_table_eit *eit = kzalloc(sizeof(*eit), GFP_KERNEL); - + struct vidtv_psi_table_eit *eit; const u16 SYNTAX = 0x1; const u16 ONE = 0x1; const u16 ONES = 0x03; + eit = kzalloc(sizeof(*eit), GFP_KERNEL); + if (!eit) + return NULL; + eit->header.table_id = 0x4e; //actual_transport_stream: present/following eit->header.bitfield = cpu_to_be16((SYNTAX << 15) | (ONE << 14) | (ONES << 12)); @@ -1906,9 +1971,13 @@ u32 vidtv_psi_eit_write_into(struct vidtv_psi_eit_write_args args) struct vidtv_psi_table_eit_event *vidtv_psi_eit_event_init(struct vidtv_psi_table_eit_event *head, u16 event_id) { - struct vidtv_psi_table_eit_event *e = kzalloc(sizeof(*e), GFP_KERNEL); + struct vidtv_psi_table_eit_event *e; const u8 DURATION_ONE_HOUR[] = {1, 0, 0}; + e = kzalloc(sizeof(*e), GFP_KERNEL); + if (!e) + return NULL; + e->event_id = cpu_to_be16(event_id); memset(e->start_time, 0xff, sizeof(e->start_time)); //todo: 0xff means 'unspecified' memcpy(e->duration, DURATION_ONE_HOUR, sizeof(e->duration)); //todo, default to this for now diff --git a/drivers/media/test-drivers/vidtv/vidtv_s302m.c b/drivers/media/test-drivers/vidtv/vidtv_s302m.c index ec88af63a74e..146e4e9d361b 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_s302m.c +++ b/drivers/media/test-drivers/vidtv/vidtv_s302m.c @@ -144,7 +144,11 @@ static const struct tone_duration beethoven_5th_symphony[] = { static struct vidtv_access_unit *vidtv_s302m_access_unit_init(struct vidtv_access_unit *head) { - struct vidtv_access_unit *au = kzalloc(sizeof(*au), GFP_KERNEL); + struct vidtv_access_unit *au; + + au = kzalloc(sizeof(*au), GFP_KERNEL); + if (!au) + return NULL; if (head) { while (head->next) @@ -441,9 +445,13 @@ static u32 vidtv_s302m_clear(struct vidtv_encoder *e) struct vidtv_encoder *vidtv_s302m_encoder_init(struct vidtv_s302m_encoder_init_args args) { - struct vidtv_encoder *e = kzalloc(sizeof(*e), GFP_KERNEL); + struct vidtv_encoder *e; u32 priv_sz = sizeof(struct vidtv_s302m_ctx); - struct vidtv_s302m_ctx *ctx = kzalloc(priv_sz, GFP_KERNEL); + struct vidtv_s302m_ctx *ctx; + + e = kzalloc(sizeof(*e), GFP_KERNEL); + if (!e) + return NULL; e->id = S302M; @@ -461,6 +469,11 @@ struct vidtv_encoder e->src_buf_offset = 0; e->is_video_encoder = false; + + ctx = kzalloc(priv_sz, GFP_KERNEL); + if (!ctx) + return NULL; + e->ctx = ctx; ctx->last_duration = 0; -- cgit v1.2.3 From 31e82355a14ede525b96e1f300acebb29052915f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 17 Nov 2020 17:38:36 +0100 Subject: media: vidtv: don't use recursive functions The Linux stack is too short. So, using recursive functions is a very bad idea. Convert those into non-recursive ones. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_psi.c | 75 +++++++++++++++------------- 1 file changed, 41 insertions(+), 34 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c index f7caa96c0ee8..b31a29f46bde 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.c +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c @@ -951,25 +951,29 @@ vidtv_psi_pat_program_assign(struct vidtv_psi_table_pat *pat, { /* This function transfers ownership of p to the table */ - u16 program_count = 0; - struct vidtv_psi_table_pat_program *program = p; + u16 program_count; + struct vidtv_psi_table_pat_program *program; - if (p == pat->program) - return; + do { + program_count = 0; + program = p; - while (program) { - ++program_count; - program = program->next; - } + if (p == pat->program) + return; + + while (program) { + ++program_count; + program = program->next; + } - pat->programs = program_count; - pat->program = p; + pat->programs = program_count; + pat->program = p; - /* Recompute section length */ - vidtv_psi_pat_table_update_sec_len(pat); + /* Recompute section length */ + vidtv_psi_pat_table_update_sec_len(pat); - if (vidtv_psi_get_sec_len(&pat->header) > MAX_SECTION_LEN) - vidtv_psi_pat_program_assign(pat, NULL); + p = NULL; + } while (vidtv_psi_get_sec_len(&pat->header) > MAX_SECTION_LEN); vidtv_psi_update_version_num(&pat->header); } @@ -1124,15 +1128,16 @@ void vidtv_psi_pmt_stream_destroy(struct vidtv_psi_table_pmt_stream *s) void vidtv_psi_pmt_stream_assign(struct vidtv_psi_table_pmt *pmt, struct vidtv_psi_table_pmt_stream *s) { - /* This function transfers ownership of s to the table */ - if (s == pmt->stream) - return; + do { + /* This function transfers ownership of s to the table */ + if (s == pmt->stream) + return; - pmt->stream = s; - vidtv_psi_pmt_table_update_sec_len(pmt); + pmt->stream = s; + vidtv_psi_pmt_table_update_sec_len(pmt); - if (vidtv_psi_get_sec_len(&pmt->header) > MAX_SECTION_LEN) - vidtv_psi_pmt_stream_assign(pmt, NULL); + s = NULL; + } while (vidtv_psi_get_sec_len(&pmt->header) > MAX_SECTION_LEN); vidtv_psi_update_version_num(&pmt->header); } @@ -1500,16 +1505,17 @@ void vidtv_psi_sdt_service_assign(struct vidtv_psi_table_sdt *sdt, struct vidtv_psi_table_sdt_service *service) { - if (service == sdt->service) - return; + do { + if (service == sdt->service) + return; - sdt->service = service; + sdt->service = service; - /* recompute section length */ - vidtv_psi_sdt_table_update_sec_len(sdt); + /* recompute section length */ + vidtv_psi_sdt_table_update_sec_len(sdt); - if (vidtv_psi_get_sec_len(&sdt->header) > MAX_SECTION_LEN) - vidtv_psi_sdt_service_assign(sdt, NULL); + service = NULL; + } while (vidtv_psi_get_sec_len(&sdt->header) > MAX_SECTION_LEN); vidtv_psi_update_version_num(&sdt->header); } @@ -1832,14 +1838,15 @@ void vidtv_psi_eit_table_update_sec_len(struct vidtv_psi_table_eit *eit) void vidtv_psi_eit_event_assign(struct vidtv_psi_table_eit *eit, struct vidtv_psi_table_eit_event *e) { - if (e == eit->event) - return; + do { + if (e == eit->event) + return; - eit->event = e; - vidtv_psi_eit_table_update_sec_len(eit); + eit->event = e; + vidtv_psi_eit_table_update_sec_len(eit); - if (vidtv_psi_get_sec_len(&eit->header) > EIT_MAX_SECTION_LEN) - vidtv_psi_eit_event_assign(eit, NULL); + e = NULL; + } while (vidtv_psi_get_sec_len(&eit->header) > EIT_MAX_SECTION_LEN); vidtv_psi_update_version_num(&eit->header); } -- cgit v1.2.3 From af66e03edd4d46c7c37f6360dab3ed5953f36943 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 19 Nov 2020 09:41:22 +0100 Subject: media: vidtv: fix the name of the program MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While the original plan was to use the first movement of the 5th Symphony, it was opted to use the Für Elise song, instead. Fix it. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_channel.c | 2 +- drivers/media/test-drivers/vidtv/vidtv_s302m.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_channel.c b/drivers/media/test-drivers/vidtv/vidtv_channel.c index ddfeecd381e6..f64a68dea234 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_channel.c +++ b/drivers/media/test-drivers/vidtv/vidtv_channel.c @@ -61,7 +61,7 @@ struct vidtv_channel char *provider = ENCODING_ISO8859_15 "LinuxTV.org"; char *iso_language_code = ENCODING_ISO8859_15 "eng"; char *event_name = ENCODING_ISO8859_15 "Beethoven Music"; - char *event_text = ENCODING_ISO8859_15 "Beethoven's 5th Symphony"; + char *event_text = ENCODING_ISO8859_15 "Beethoven's Für Elise"; const u16 s302m_beethoven_event_id = 1; struct vidtv_channel *s302m; struct vidtv_s302m_encoder_init_args encoder_args = {}; diff --git a/drivers/media/test-drivers/vidtv/vidtv_s302m.c b/drivers/media/test-drivers/vidtv/vidtv_s302m.c index 146e4e9d361b..cbf89530aafe 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_s302m.c +++ b/drivers/media/test-drivers/vidtv/vidtv_s302m.c @@ -79,7 +79,7 @@ struct tone_duration { }; #define COMPASS 120 /* beats per minute (Allegro) */ -static const struct tone_duration beethoven_5th_symphony[] = { +static const struct tone_duration beethoven_fur_elise[] = { { NOTE_E_6, 128}, { NOTE_DS_6, 128}, { NOTE_E_6, 128}, { NOTE_DS_6, 128}, { NOTE_E_6, 128}, { NOTE_B_5, 128}, { NOTE_D_6, 128}, { NOTE_C_6, 128}, { NOTE_A_3, 128}, @@ -238,14 +238,14 @@ static u16 vidtv_s302m_get_sample(struct vidtv_encoder *e) if (!e->src_buf) { /* * Simple tone generator: play the tones at the - * beethoven_5th_symphony array. + * beethoven_fur_elise array. */ if (ctx->last_duration <= 0) { - if (e->src_buf_offset >= ARRAY_SIZE(beethoven_5th_symphony)) + if (e->src_buf_offset >= ARRAY_SIZE(beethoven_fur_elise)) e->src_buf_offset = 0; - ctx->last_tone = beethoven_5th_symphony[e->src_buf_offset].note; - ctx->last_duration = beethoven_5th_symphony[e->src_buf_offset].duration * + ctx->last_tone = beethoven_fur_elise[e->src_buf_offset].note; + ctx->last_duration = beethoven_fur_elise[e->src_buf_offset].duration * S302M_SAMPLING_RATE_HZ / COMPASS / 5; e->src_buf_offset++; ctx->note_offset = 0; -- cgit v1.2.3 From ab6bad0a4db69009fb7b2a50b8929b2bcaf7824d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 19 Nov 2020 11:20:46 +0100 Subject: media: vidtv: fix the tone generator logic The tone generator logic were repeating the song after the first silent. There's also a wrong logic at the note offset calculus, which may create some noise. Fix it. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_s302m.c | 14 ++++---------- drivers/media/test-drivers/vidtv/vidtv_s302m.h | 2 +- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_s302m.c b/drivers/media/test-drivers/vidtv/vidtv_s302m.c index cbf89530aafe..fdb3d649c516 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_s302m.c +++ b/drivers/media/test-drivers/vidtv/vidtv_s302m.c @@ -253,18 +253,12 @@ static u16 vidtv_s302m_get_sample(struct vidtv_encoder *e) ctx->last_duration--; } - /* Handle silent */ - if (!ctx->last_tone) { - e->src_buf_offset = 0; + /* Handle pause notes */ + if (!ctx->last_tone) return 0x8000; - } - - pos = (2 * PI * ctx->note_offset * ctx->last_tone / S302M_SAMPLING_RATE_HZ); - if (pos == 360) - ctx->note_offset = 0; - else - ctx->note_offset++; + pos = (2 * PI * ctx->note_offset * ctx->last_tone) / S302M_SAMPLING_RATE_HZ; + ctx->note_offset++; return (fixp_sin32(pos % (2 * PI)) >> 16) + 0x8000; } diff --git a/drivers/media/test-drivers/vidtv/vidtv_s302m.h b/drivers/media/test-drivers/vidtv/vidtv_s302m.h index a0101734e758..e990b755bb20 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_s302m.h +++ b/drivers/media/test-drivers/vidtv/vidtv_s302m.h @@ -39,7 +39,7 @@ struct vidtv_s302m_ctx { u32 frame_index; u32 au_count; int last_duration; - int note_offset; + unsigned int note_offset; enum musical_notes last_tone; }; -- cgit v1.2.3 From 0d271a79c702d4b986809cb3acfbe8911bba892e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 19 Nov 2020 11:20:38 +0100 Subject: media: vidtv: fix some notes at the tone generator The sheet music used to generate the tones had a few polyphonic notes. Due to that, its conversion to a tones sequence had a few errors. Also, due to a bug at the tone generator, it was missing the pause at the initial compass. Fix them. While here, reduce the compass to 100bpm. The music was converted from a Music XML file using this small script: my $count = 0; my $silent = 0; my $note; my $octave; print "\t"; while (<>) { $note = $1 if (m,\(.*)\,); $octave = "_$1" if (m,\(.*)\,); if (m,\1\,) { $note .= "S"; $sharp = 1; } if (m,\,) { $note = "SILENT"; $silent = 1; } if (m,\(.*)\,) { printf "{ NOTE_${note}${octave}, %d},", $1 * 128 / 480; $count++; if ($silent || $count >= 3) { print "\n\t"; $count = 0; $silent = 0; } else { print " "; print " " if (!$sharp); } $sharp = 0; $note = ""; $octave = ""; }; }; print "\n"; Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_s302m.c | 38 ++++++++++++++------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_s302m.c b/drivers/media/test-drivers/vidtv/vidtv_s302m.c index fdb3d649c516..569e7a50129f 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_s302m.c +++ b/drivers/media/test-drivers/vidtv/vidtv_s302m.c @@ -78,8 +78,9 @@ struct tone_duration { int duration; }; -#define COMPASS 120 /* beats per minute (Allegro) */ +#define COMPASS 100 /* beats per minute */ static const struct tone_duration beethoven_fur_elise[] = { + { NOTE_SILENT, 512}, { NOTE_E_6, 128}, { NOTE_DS_6, 128}, { NOTE_E_6, 128}, { NOTE_DS_6, 128}, { NOTE_E_6, 128}, { NOTE_B_5, 128}, { NOTE_D_6, 128}, { NOTE_C_6, 128}, { NOTE_A_3, 128}, @@ -120,26 +121,27 @@ static const struct tone_duration beethoven_fur_elise[] = { { NOTE_E_5, 128}, { NOTE_D_5, 128}, { NOTE_A_3, 128}, { NOTE_E_4, 128}, { NOTE_A_4, 128}, { NOTE_E_4, 128}, { NOTE_D_5, 128}, { NOTE_C_5, 128}, { NOTE_E_3, 128}, - { NOTE_E_4, 128}, { NOTE_E_5, 255}, { NOTE_E_6, 128}, - { NOTE_E_5, 128}, { NOTE_E_6, 128}, { NOTE_E_5, 255}, + { NOTE_E_4, 128}, { NOTE_E_5, 128}, { NOTE_E_5, 128}, + { NOTE_E_6, 128}, { NOTE_E_5, 128}, { NOTE_E_6, 128}, + { NOTE_E_5, 128}, { NOTE_E_5, 128}, { NOTE_DS_5, 128}, + { NOTE_E_5, 128}, { NOTE_DS_6, 128}, { NOTE_E_6, 128}, { NOTE_DS_5, 128}, { NOTE_E_5, 128}, { NOTE_DS_6, 128}, - { NOTE_E_6, 128}, { NOTE_DS_5, 128}, { NOTE_E_5, 128}, - { NOTE_DS_6, 128}, { NOTE_E_6, 128}, { NOTE_DS_6, 128}, { NOTE_E_6, 128}, { NOTE_DS_6, 128}, { NOTE_E_6, 128}, - { NOTE_B_5, 128}, { NOTE_D_6, 128}, { NOTE_C_6, 128}, - { NOTE_A_3, 128}, { NOTE_E_4, 128}, { NOTE_A_4, 128}, - { NOTE_C_5, 128}, { NOTE_E_5, 128}, { NOTE_A_5, 128}, - { NOTE_E_3, 128}, { NOTE_E_4, 128}, { NOTE_GS_4, 128}, - { NOTE_E_5, 128}, { NOTE_GS_5, 128}, { NOTE_B_5, 128}, - { NOTE_A_3, 128}, { NOTE_E_4, 128}, { NOTE_A_4, 128}, - { NOTE_E_5, 128}, { NOTE_E_6, 128}, { NOTE_DS_6, 128}, + { NOTE_DS_6, 128}, { NOTE_E_6, 128}, { NOTE_B_5, 128}, + { NOTE_D_6, 128}, { NOTE_C_6, 128}, { NOTE_A_3, 128}, + { NOTE_E_4, 128}, { NOTE_A_4, 128}, { NOTE_C_5, 128}, + { NOTE_E_5, 128}, { NOTE_A_5, 128}, { NOTE_E_3, 128}, + { NOTE_E_4, 128}, { NOTE_GS_4, 128}, { NOTE_E_5, 128}, + { NOTE_GS_5, 128}, { NOTE_B_5, 128}, { NOTE_A_3, 128}, + { NOTE_E_4, 128}, { NOTE_A_4, 128}, { NOTE_E_5, 128}, { NOTE_E_6, 128}, { NOTE_DS_6, 128}, { NOTE_E_6, 128}, - { NOTE_B_5, 128}, { NOTE_D_6, 128}, { NOTE_C_6, 128}, - { NOTE_A_3, 128}, { NOTE_E_4, 128}, { NOTE_A_4, 128}, - { NOTE_C_5, 128}, { NOTE_E_5, 128}, { NOTE_A_5, 128}, - { NOTE_E_3, 128}, { NOTE_E_4, 128}, { NOTE_GS_4, 128}, - { NOTE_E_5, 128}, { NOTE_C_6, 128}, { NOTE_B_5, 128}, - { NOTE_C_5, 255}, { NOTE_C_5, 255}, { NOTE_SILENT, 512}, + { NOTE_DS_6, 128}, { NOTE_E_6, 128}, { NOTE_B_5, 128}, + { NOTE_D_6, 128}, { NOTE_C_6, 128}, { NOTE_A_3, 128}, + { NOTE_E_4, 128}, { NOTE_A_4, 128}, { NOTE_C_5, 128}, + { NOTE_E_5, 128}, { NOTE_A_5, 128}, { NOTE_E_3, 128}, + { NOTE_E_4, 128}, { NOTE_GS_4, 128}, { NOTE_E_5, 128}, + { NOTE_C_6, 128}, { NOTE_B_5, 128}, { NOTE_A_5, 512}, + { NOTE_SILENT, 256}, }; static struct vidtv_access_unit *vidtv_s302m_access_unit_init(struct vidtv_access_unit *head) -- cgit v1.2.3 From 0a33ab1682b44ac0b4128ada7ace9f7a0ef6b59c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 22 Sep 2020 10:28:12 +0200 Subject: media: vidtv: avoid data copy when initializing the multiplexer Initialize the fields of the arguments directly when declaring it, and pass the args as a pointer, instead of copying them. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_bridge.c | 28 +++++++++++++------------ drivers/media/test-drivers/vidtv/vidtv_mux.c | 28 ++++++++++++------------- drivers/media/test-drivers/vidtv/vidtv_mux.h | 2 +- 3 files changed, 30 insertions(+), 28 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_bridge.c b/drivers/media/test-drivers/vidtv/vidtv_bridge.c index e846aaab2c44..3fc7bf00a3e5 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_bridge.c +++ b/drivers/media/test-drivers/vidtv/vidtv_bridge.c @@ -161,7 +161,17 @@ vidtv_bridge_on_new_pkts_avail(void *priv, u8 *buf, u32 npkts) static int vidtv_start_streaming(struct vidtv_dvb *dvb) { - struct vidtv_mux_init_args mux_args = {0}; + struct vidtv_mux_init_args mux_args = { + .mux_rate_kbytes_sec = mux_rate_kbytes_sec, + .on_new_packets_available_cb = vidtv_bridge_on_new_pkts_avail, + .pcr_period_usecs = pcr_period_msec * USEC_PER_MSEC, + .si_period_usecs = si_period_msec * USEC_PER_MSEC, + .pcr_pid = pcr_pid, + .transport_stream_id = VIDTV_DEFAULT_TS_ID, + .network_id = VIDTV_DEFAULT_NETWORK_ID, + .network_name = VIDTV_DEFAULT_NETWORK_NAME, + .priv = dvb, + }; struct device *dev = &dvb->pdev->dev; u32 mux_buf_sz; @@ -170,21 +180,13 @@ static int vidtv_start_streaming(struct vidtv_dvb *dvb) return 0; } - mux_buf_sz = (mux_buf_sz_pkts) ? mux_buf_sz_pkts : vidtv_bridge_mux_buf_sz_for_mux_rate(); + mux_buf_sz = (mux_buf_sz_pkts) ? mux_buf_sz_pkts : + vidtv_bridge_mux_buf_sz_for_mux_rate(); - mux_args.mux_rate_kbytes_sec = mux_rate_kbytes_sec; - mux_args.on_new_packets_available_cb = vidtv_bridge_on_new_pkts_avail; - mux_args.mux_buf_sz = mux_buf_sz; - mux_args.pcr_period_usecs = pcr_period_msec * 1000; - mux_args.si_period_usecs = si_period_msec * 1000; - mux_args.pcr_pid = pcr_pid; - mux_args.transport_stream_id = VIDTV_DEFAULT_TS_ID; - mux_args.network_id = VIDTV_DEFAULT_NETWORK_ID, - mux_args.network_name = VIDTV_DEFAULT_NETWORK_NAME, - mux_args.priv = dvb; + mux_args.mux_buf_sz = mux_buf_sz; dvb->streaming = true; - dvb->mux = vidtv_mux_init(dvb->fe[0], dev, mux_args); + dvb->mux = vidtv_mux_init(dvb->fe[0], dev, &mux_args); if (!dvb->mux) return -ENOMEM; vidtv_mux_start_thread(dvb->mux); diff --git a/drivers/media/test-drivers/vidtv/vidtv_mux.c b/drivers/media/test-drivers/vidtv/vidtv_mux.c index bba3f2315531..89b19f0844b8 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_mux.c +++ b/drivers/media/test-drivers/vidtv/vidtv_mux.c @@ -466,7 +466,7 @@ void vidtv_mux_stop_thread(struct vidtv_mux *m) struct vidtv_mux *vidtv_mux_init(struct dvb_frontend *fe, struct device *dev, - struct vidtv_mux_init_args args) + struct vidtv_mux_init_args *args) { struct vidtv_mux *m; @@ -476,28 +476,28 @@ struct vidtv_mux *vidtv_mux_init(struct dvb_frontend *fe, m->dev = dev; m->fe = fe; - m->timing.pcr_period_usecs = args.pcr_period_usecs; - m->timing.si_period_usecs = args.si_period_usecs; + m->timing.pcr_period_usecs = args->pcr_period_usecs; + m->timing.si_period_usecs = args->si_period_usecs; - m->mux_rate_kbytes_sec = args.mux_rate_kbytes_sec; + m->mux_rate_kbytes_sec = args->mux_rate_kbytes_sec; - m->on_new_packets_available_cb = args.on_new_packets_available_cb; + m->on_new_packets_available_cb = args->on_new_packets_available_cb; - m->mux_buf = vzalloc(args.mux_buf_sz); + m->mux_buf = vzalloc(args->mux_buf_sz); if (!m->mux_buf) goto free_mux; - m->mux_buf_sz = args.mux_buf_sz; + m->mux_buf_sz = args->mux_buf_sz; - m->pcr_pid = args.pcr_pid; - m->transport_stream_id = args.transport_stream_id; - m->priv = args.priv; - m->network_id = args.network_id; - m->network_name = kstrdup(args.network_name, GFP_KERNEL); + m->pcr_pid = args->pcr_pid; + m->transport_stream_id = args->transport_stream_id; + m->priv = args->priv; + m->network_id = args->network_id; + m->network_name = kstrdup(args->network_name, GFP_KERNEL); m->timing.current_jiffies = get_jiffies_64(); - if (args.channels) - m->channels = args.channels; + if (args->channels) + m->channels = args->channels; else if (vidtv_channels_init(m) < 0) goto free_mux_buf; diff --git a/drivers/media/test-drivers/vidtv/vidtv_mux.h b/drivers/media/test-drivers/vidtv/vidtv_mux.h index 005b707f1445..e186094c4fb7 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_mux.h +++ b/drivers/media/test-drivers/vidtv/vidtv_mux.h @@ -170,7 +170,7 @@ struct vidtv_mux_init_args { struct vidtv_mux *vidtv_mux_init(struct dvb_frontend *fe, struct device *dev, - struct vidtv_mux_init_args args); + struct vidtv_mux_init_args *args); void vidtv_mux_destroy(struct vidtv_mux *m); void vidtv_mux_start_thread(struct vidtv_mux *m); -- cgit v1.2.3 From 163d72a2d3ec7e0bc41b943fed7667f7cbfc760f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 22 Sep 2020 11:01:17 +0200 Subject: media: vidtv: avoid copying data for PES structs Minimize the number of data copies and initialization at the code, passing them as pointers instead of duplicating the data. The only case where we're keeping the data copy is at vidtv_pes_write_h(), as it needs a copy of the passed arguments. On such case, we're being more explicit. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_mux.c | 30 +++-- drivers/media/test-drivers/vidtv/vidtv_pes.c | 178 +++++++++++++-------------- drivers/media/test-drivers/vidtv/vidtv_pes.h | 2 +- 3 files changed, 102 insertions(+), 108 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_mux.c b/drivers/media/test-drivers/vidtv/vidtv_mux.c index 89b19f0844b8..eb24e27b7f5f 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_mux.c +++ b/drivers/media/test-drivers/vidtv/vidtv_mux.c @@ -270,22 +270,28 @@ static u32 vidtv_mux_packetize_access_units(struct vidtv_mux *m, struct vidtv_encoder *e) { u32 nbytes = 0; - - struct pes_write_args args = {}; + struct pes_write_args args = { + .dest_buf = m->mux_buf, + .dest_buf_sz = m->mux_buf_sz, + .pid = be16_to_cpu(e->es_pid), + .encoder_id = e->id, + .stream_id = be16_to_cpu(e->stream_id), + .send_pts = true, /* forbidden value '01'... */ + .send_dts = false, /* ...for PTS_DTS flags */ + }; u32 initial_offset = m->mux_buf_offset; struct vidtv_access_unit *au = e->access_units; - u8 *buf = NULL; - struct vidtv_mux_pid_ctx *pid_ctx = vidtv_mux_create_pid_ctx_once(m, - be16_to_cpu(e->es_pid)); + struct vidtv_mux_pid_ctx *pid_ctx; - args.dest_buf = m->mux_buf; - args.dest_buf_sz = m->mux_buf_sz; - args.pid = be16_to_cpu(e->es_pid); - args.encoder_id = e->id; + /* see SMPTE 302M clause 6.4 */ + if (args.encoder_id == S302M) { + args.send_dts = false; + args.send_pts = true; + } + + pid_ctx = vidtv_mux_create_pid_ctx_once(m, be16_to_cpu(e->es_pid)); args.continuity_counter = &pid_ctx->cc; - args.stream_id = be16_to_cpu(e->stream_id); - args.send_pts = true; while (au) { buf = e->encoder_buf + au->offset; @@ -295,7 +301,7 @@ static u32 vidtv_mux_packetize_access_units(struct vidtv_mux *m, args.pts = au->pts; args.pcr = m->timing.clk; - m->mux_buf_offset += vidtv_pes_write_into(args); + m->mux_buf_offset += vidtv_pes_write_into(&args); au = au->next; } diff --git a/drivers/media/test-drivers/vidtv/vidtv_pes.c b/drivers/media/test-drivers/vidtv/vidtv_pes.c index 102352d398ed..782e5e7fbb02 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_pes.c +++ b/drivers/media/test-drivers/vidtv/vidtv_pes.c @@ -56,7 +56,7 @@ static u32 vidtv_pes_h_get_len(bool send_pts, bool send_dts) return len; } -static u32 vidtv_pes_write_header_stuffing(struct pes_header_write_args args) +static u32 vidtv_pes_write_header_stuffing(struct pes_header_write_args *args) { /* * This is a fixed 8-bit value equal to '0xFF' that can be inserted @@ -64,20 +64,20 @@ static u32 vidtv_pes_write_header_stuffing(struct pes_header_write_args args) * It is discarded by the decoder. No more than 32 stuffing bytes shall * be present in one PES packet header. */ - if (args.n_pes_h_s_bytes > PES_HEADER_MAX_STUFFING_BYTES) { + if (args->n_pes_h_s_bytes > PES_HEADER_MAX_STUFFING_BYTES) { pr_warn_ratelimited("More than %d stuffing bytes in PES packet header\n", PES_HEADER_MAX_STUFFING_BYTES); - args.n_pes_h_s_bytes = PES_HEADER_MAX_STUFFING_BYTES; + args->n_pes_h_s_bytes = PES_HEADER_MAX_STUFFING_BYTES; } - return vidtv_memset(args.dest_buf, - args.dest_offset, - args.dest_buf_sz, + return vidtv_memset(args->dest_buf, + args->dest_offset, + args->dest_buf_sz, TS_FILL_BYTE, - args.n_pes_h_s_bytes); + args->n_pes_h_s_bytes); } -static u32 vidtv_pes_write_pts_dts(struct pes_header_write_args args) +static u32 vidtv_pes_write_pts_dts(struct pes_header_write_args *args) { u32 nbytes = 0; /* the number of bytes written by this function */ @@ -89,7 +89,7 @@ static u32 vidtv_pes_write_pts_dts(struct pes_header_write_args args) u64 mask2; u64 mask3; - if (!args.send_pts && args.send_dts) + if (!args->send_pts && args->send_dts) return 0; mask1 = GENMASK_ULL(32, 30); @@ -97,80 +97,81 @@ static u32 vidtv_pes_write_pts_dts(struct pes_header_write_args args) mask3 = GENMASK_ULL(14, 0); /* see ISO/IEC 13818-1 : 2000 p. 32 */ - if (args.send_pts && args.send_dts) { - pts_dts.pts1 = (0x3 << 4) | ((args.pts & mask1) >> 29) | 0x1; - pts_dts.pts2 = cpu_to_be16(((args.pts & mask2) >> 14) | 0x1); - pts_dts.pts3 = cpu_to_be16(((args.pts & mask3) << 1) | 0x1); + if (args->send_pts && args->send_dts) { + pts_dts.pts1 = (0x3 << 4) | ((args->pts & mask1) >> 29) | 0x1; + pts_dts.pts2 = cpu_to_be16(((args->pts & mask2) >> 14) | 0x1); + pts_dts.pts3 = cpu_to_be16(((args->pts & mask3) << 1) | 0x1); - pts_dts.dts1 = (0x1 << 4) | ((args.dts & mask1) >> 29) | 0x1; - pts_dts.dts2 = cpu_to_be16(((args.dts & mask2) >> 14) | 0x1); - pts_dts.dts3 = cpu_to_be16(((args.dts & mask3) << 1) | 0x1); + pts_dts.dts1 = (0x1 << 4) | ((args->dts & mask1) >> 29) | 0x1; + pts_dts.dts2 = cpu_to_be16(((args->dts & mask2) >> 14) | 0x1); + pts_dts.dts3 = cpu_to_be16(((args->dts & mask3) << 1) | 0x1); op = &pts_dts; op_sz = sizeof(pts_dts); - } else if (args.send_pts) { - pts.pts1 = (0x1 << 5) | ((args.pts & mask1) >> 29) | 0x1; - pts.pts2 = cpu_to_be16(((args.pts & mask2) >> 14) | 0x1); - pts.pts3 = cpu_to_be16(((args.pts & mask3) << 1) | 0x1); + } else if (args->send_pts) { + pts.pts1 = (0x1 << 5) | ((args->pts & mask1) >> 29) | 0x1; + pts.pts2 = cpu_to_be16(((args->pts & mask2) >> 14) | 0x1); + pts.pts3 = cpu_to_be16(((args->pts & mask3) << 1) | 0x1); op = &pts; op_sz = sizeof(pts); } /* copy PTS/DTS optional */ - nbytes += vidtv_memcpy(args.dest_buf, - args.dest_offset + nbytes, - args.dest_buf_sz, + nbytes += vidtv_memcpy(args->dest_buf, + args->dest_offset + nbytes, + args->dest_buf_sz, op, op_sz); return nbytes; } -static u32 vidtv_pes_write_h(struct pes_header_write_args args) +static u32 vidtv_pes_write_h(struct pes_header_write_args *args) { u32 nbytes = 0; /* the number of bytes written by this function */ struct vidtv_mpeg_pes pes_header = {}; struct vidtv_pes_optional pes_optional = {}; - struct pes_header_write_args pts_dts_args = args; - u32 stream_id = (args.encoder_id == S302M) ? PRIVATE_STREAM_1_ID : args.stream_id; + struct pes_header_write_args pts_dts_args; + u32 stream_id = (args->encoder_id == S302M) ? PRIVATE_STREAM_1_ID : args->stream_id; u16 pes_opt_bitfield = 0x01 << 15; pes_header.bitfield = cpu_to_be32((PES_START_CODE_PREFIX << 8) | stream_id); - pes_header.length = cpu_to_be16(vidtv_pes_op_get_len(args.send_pts, - args.send_dts) + - args.access_unit_len); + pes_header.length = cpu_to_be16(vidtv_pes_op_get_len(args->send_pts, + args->send_dts) + + args->access_unit_len); - if (args.send_pts && args.send_dts) + if (args->send_pts && args->send_dts) pes_opt_bitfield |= (0x3 << 6); - else if (args.send_pts) + else if (args->send_pts) pes_opt_bitfield |= (0x1 << 7); pes_optional.bitfield = cpu_to_be16(pes_opt_bitfield); - pes_optional.length = vidtv_pes_op_get_len(args.send_pts, args.send_dts) + - args.n_pes_h_s_bytes - + pes_optional.length = vidtv_pes_op_get_len(args->send_pts, args->send_dts) + + args->n_pes_h_s_bytes - sizeof(struct vidtv_pes_optional); /* copy header */ - nbytes += vidtv_memcpy(args.dest_buf, - args.dest_offset + nbytes, - args.dest_buf_sz, + nbytes += vidtv_memcpy(args->dest_buf, + args->dest_offset + nbytes, + args->dest_buf_sz, &pes_header, sizeof(pes_header)); /* copy optional header bits */ - nbytes += vidtv_memcpy(args.dest_buf, - args.dest_offset + nbytes, - args.dest_buf_sz, + nbytes += vidtv_memcpy(args->dest_buf, + args->dest_offset + nbytes, + args->dest_buf_sz, &pes_optional, sizeof(pes_optional)); /* copy the timing information */ - pts_dts_args.dest_offset = args.dest_offset + nbytes; - nbytes += vidtv_pes_write_pts_dts(pts_dts_args); + pts_dts_args = *args; + pts_dts_args.dest_offset = args->dest_offset + nbytes; + nbytes += vidtv_pes_write_pts_dts(&pts_dts_args); /* write any PES header stuffing */ nbytes += vidtv_pes_write_header_stuffing(args); @@ -299,14 +300,31 @@ static u32 vidtv_pes_write_ts_h(struct pes_ts_header_write_args args, return nbytes; } -u32 vidtv_pes_write_into(struct pes_write_args args) +u32 vidtv_pes_write_into(struct pes_write_args *args) { - u32 unaligned_bytes = (args.dest_offset % TS_PACKET_LEN); - struct pes_ts_header_write_args ts_header_args = {}; - struct pes_header_write_args pes_header_args = {}; - u32 remaining_len = args.access_unit_len; + u32 unaligned_bytes = (args->dest_offset % TS_PACKET_LEN); + struct pes_ts_header_write_args ts_header_args = { + .dest_buf = args->dest_buf, + .dest_buf_sz = args->dest_buf_sz, + .pid = args->pid, + .pcr = args->pcr, + .continuity_counter = args->continuity_counter, + }; + struct pes_header_write_args pes_header_args = { + .dest_buf = args->dest_buf, + .dest_buf_sz = args->dest_buf_sz, + .encoder_id = args->encoder_id, + .send_pts = args->send_pts, + .pts = args->pts, + .send_dts = args->send_dts, + .dts = args->dts, + .stream_id = args->stream_id, + .n_pes_h_s_bytes = args->n_pes_h_s_bytes, + .access_unit_len = args->access_unit_len, + }; + u32 remaining_len = args->access_unit_len; bool wrote_pes_header = false; - u64 last_pcr = args.pcr; + u64 last_pcr = args->pcr; bool need_pcr = true; u32 available_space; u32 payload_size; @@ -317,25 +335,13 @@ u32 vidtv_pes_write_into(struct pes_write_args args) pr_warn_ratelimited("buffer is misaligned, while starting PES\n"); /* forcibly align and hope for the best */ - nbytes += vidtv_memset(args.dest_buf, - args.dest_offset + nbytes, - args.dest_buf_sz, + nbytes += vidtv_memset(args->dest_buf, + args->dest_offset + nbytes, + args->dest_buf_sz, TS_FILL_BYTE, TS_PACKET_LEN - unaligned_bytes); } - if (args.send_dts && !args.send_pts) { - pr_warn_ratelimited("forbidden value '01' for PTS_DTS flags\n"); - args.send_pts = true; - args.pts = args.dts; - } - - /* see SMPTE 302M clause 6.4 */ - if (args.encoder_id == S302M) { - args.send_dts = false; - args.send_pts = true; - } - while (remaining_len) { available_space = TS_PAYLOAD_LEN; /* @@ -344,14 +350,14 @@ u32 vidtv_pes_write_into(struct pes_write_args args) * the space needed for the TS header _and_ for the PES header */ if (!wrote_pes_header) - available_space -= vidtv_pes_h_get_len(args.send_pts, - args.send_dts); + available_space -= vidtv_pes_h_get_len(args->send_pts, + args->send_dts); /* * if the encoder has inserted stuffing bytes in the PES * header, account for them. */ - available_space -= args.n_pes_h_s_bytes; + available_space -= args->n_pes_h_s_bytes; /* Take the extra adaptation into account if need to send PCR */ if (need_pcr) { @@ -386,14 +392,9 @@ u32 vidtv_pes_write_into(struct pes_write_args args) } /* write ts header */ - ts_header_args.dest_buf = args.dest_buf; - ts_header_args.dest_offset = args.dest_offset + nbytes; - ts_header_args.dest_buf_sz = args.dest_buf_sz; - ts_header_args.pid = args.pid; - ts_header_args.pcr = args.pcr; - ts_header_args.continuity_counter = args.continuity_counter; - ts_header_args.wrote_pes_header = wrote_pes_header; - ts_header_args.n_stuffing_bytes = stuff_bytes; + ts_header_args.dest_offset = args->dest_offset + nbytes; + ts_header_args.wrote_pes_header = wrote_pes_header; + ts_header_args.n_stuffing_bytes = stuff_bytes; nbytes += vidtv_pes_write_ts_h(ts_header_args, need_pcr, &last_pcr); @@ -402,33 +403,20 @@ u32 vidtv_pes_write_into(struct pes_write_args args) if (!wrote_pes_header) { /* write the PES header only once */ - pes_header_args.dest_buf = args.dest_buf; - - pes_header_args.dest_offset = args.dest_offset + - nbytes; - - pes_header_args.dest_buf_sz = args.dest_buf_sz; - pes_header_args.encoder_id = args.encoder_id; - pes_header_args.send_pts = args.send_pts; - pes_header_args.pts = args.pts; - pes_header_args.send_dts = args.send_dts; - pes_header_args.dts = args.dts; - pes_header_args.stream_id = args.stream_id; - pes_header_args.n_pes_h_s_bytes = args.n_pes_h_s_bytes; - pes_header_args.access_unit_len = args.access_unit_len; - - nbytes += vidtv_pes_write_h(pes_header_args); - wrote_pes_header = true; + pes_header_args.dest_offset = args->dest_offset + + nbytes; + nbytes += vidtv_pes_write_h(&pes_header_args); + wrote_pes_header = true; } /* write as much of the payload as we possibly can */ - nbytes += vidtv_memcpy(args.dest_buf, - args.dest_offset + nbytes, - args.dest_buf_sz, - args.from, + nbytes += vidtv_memcpy(args->dest_buf, + args->dest_offset + nbytes, + args->dest_buf_sz, + args->from, payload_size); - args.from += payload_size; + args->from += payload_size; remaining_len -= payload_size; } diff --git a/drivers/media/test-drivers/vidtv/vidtv_pes.h b/drivers/media/test-drivers/vidtv/vidtv_pes.h index a152693233a9..99f45056adc2 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_pes.h +++ b/drivers/media/test-drivers/vidtv/vidtv_pes.h @@ -185,6 +185,6 @@ struct pes_write_args { * equal to the size of the access unit, since we need space for PES headers, TS headers * and padding bytes, if any. */ -u32 vidtv_pes_write_into(struct pes_write_args args); +u32 vidtv_pes_write_into(struct pes_write_args *args); #endif // VIDTV_PES_H -- cgit v1.2.3 From a8bd461ca3b32468777d054d9a0e050be5a418e9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 22 Sep 2020 16:43:56 +0200 Subject: media: vidtv: do some cleanups at the driver Do some cleanups at the coding style of the driver: - remove "inline" declarations; - use reverse xmas-tree for local var declarations; - Adjust some indent to avoid breaking 80-cols; - Cleanup some comments. No functional changes. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_bridge.c | 81 ++++++----- drivers/media/test-drivers/vidtv/vidtv_channel.c | 69 ++++----- drivers/media/test-drivers/vidtv/vidtv_demod.c | 1 - drivers/media/test-drivers/vidtv/vidtv_encoder.h | 2 +- drivers/media/test-drivers/vidtv/vidtv_mux.c | 33 ++--- drivers/media/test-drivers/vidtv/vidtv_psi.c | 173 +++++++++++------------ drivers/media/test-drivers/vidtv/vidtv_s302m.c | 14 +- 7 files changed, 182 insertions(+), 191 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_bridge.c b/drivers/media/test-drivers/vidtv/vidtv_bridge.c index 3fc7bf00a3e5..d428bdb47ae4 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_bridge.c +++ b/drivers/media/test-drivers/vidtv/vidtv_bridge.c @@ -4,7 +4,8 @@ * validate the existing APIs in the media subsystem. It can also aid * developers working on userspace applications. * - * When this module is loaded, it will attempt to modprobe 'dvb_vidtv_tuner' and 'dvb_vidtv_demod'. + * When this module is loaded, it will attempt to modprobe 'dvb_vidtv_tuner' + * and 'dvb_vidtv_demod'. * * Copyright (C) 2020 Daniel W. S. Almeida */ @@ -24,18 +25,21 @@ #include "vidtv_ts.h" #include "vidtv_tuner.h" -//#define MUX_BUF_MAX_SZ -//#define MUX_BUF_MIN_SZ +#define MUX_BUF_MIN_SZ 90164 +#define MUX_BUF_MAX_SZ (MUX_BUF_MIN_SZ * 10) #define TUNER_DEFAULT_ADDR 0x68 #define DEMOD_DEFAULT_ADDR 0x60 #define VIDTV_DEFAULT_NETWORK_ID 0x744 #define VIDTV_DEFAULT_NETWORK_NAME "LinuxTV.org" -/* LNBf fake parameters: ranges used by an Universal (extended) European LNBf */ -#define LNB_CUT_FREQUENCY 11700000 -#define LNB_LOW_FREQ 9750000 -#define LNB_HIGH_FREQ 10600000 - +/* + * The LNBf fake parameters here are the ranges used by an + * Universal (extended) European LNBf, which is likely the most common LNBf + * found on Satellite digital TV system nowadays. + */ +#define LNB_CUT_FREQUENCY 11700000 /* high IF frequency */ +#define LNB_LOW_FREQ 9750000 /* low IF frequency */ +#define LNB_HIGH_FREQ 10600000 /* transition frequency */ static unsigned int drop_tslock_prob_on_low_snr; module_param(drop_tslock_prob_on_low_snr, uint, 0); @@ -94,7 +98,8 @@ MODULE_PARM_DESC(si_period_msec, "How often to send SI packets. Default: 40ms"); static unsigned int pcr_period_msec = 40; module_param(pcr_period_msec, uint, 0); -MODULE_PARM_DESC(pcr_period_msec, "How often to send PCR packets. Default: 40ms"); +MODULE_PARM_DESC(pcr_period_msec, + "How often to send PCR packets. Default: 40ms"); static unsigned int mux_rate_kbytes_sec = 4096; module_param(mux_rate_kbytes_sec, uint, 0); @@ -106,16 +111,14 @@ MODULE_PARM_DESC(pcr_pid, "PCR PID for all channels: defaults to 0x200"); static unsigned int mux_buf_sz_pkts; module_param(mux_buf_sz_pkts, uint, 0); -MODULE_PARM_DESC(mux_buf_sz_pkts, "Size for the internal mux buffer in multiples of 188 bytes"); - -#define MUX_BUF_MIN_SZ 90164 -#define MUX_BUF_MAX_SZ (MUX_BUF_MIN_SZ * 10) +MODULE_PARM_DESC(mux_buf_sz_pkts, + "Size for the internal mux buffer in multiples of 188 bytes"); static u32 vidtv_bridge_mux_buf_sz_for_mux_rate(void) { u32 max_elapsed_time_msecs = VIDTV_MAX_SLEEP_USECS / USEC_PER_MSEC; - u32 nbytes_expected; u32 mux_buf_sz = mux_buf_sz_pkts * TS_PACKET_LEN; + u32 nbytes_expected; nbytes_expected = mux_rate_kbytes_sec; nbytes_expected *= max_elapsed_time_msecs; @@ -145,14 +148,12 @@ static bool vidtv_bridge_check_demod_lock(struct vidtv_dvb *dvb, u32 n) FE_HAS_LOCK); } -static void -vidtv_bridge_on_new_pkts_avail(void *priv, u8 *buf, u32 npkts) +/* + * called on a separate thread by the mux when new packets become available + */ +static void vidtv_bridge_on_new_pkts_avail(void *priv, u8 *buf, u32 npkts) { - /* - * called on a separate thread by the mux when new packets become - * available - */ - struct vidtv_dvb *dvb = (struct vidtv_dvb *)priv; + struct vidtv_dvb *dvb = priv; /* drop packets if we lose the lock */ if (vidtv_bridge_check_demod_lock(dvb, 0)) @@ -180,8 +181,10 @@ static int vidtv_start_streaming(struct vidtv_dvb *dvb) return 0; } - mux_buf_sz = (mux_buf_sz_pkts) ? mux_buf_sz_pkts : - vidtv_bridge_mux_buf_sz_for_mux_rate(); + if (mux_buf_sz_pkts) + mux_buf_sz = mux_buf_sz_pkts; + else + mux_buf_sz = vidtv_bridge_mux_buf_sz_for_mux_rate(); mux_args.mux_buf_sz = mux_buf_sz; @@ -212,8 +215,8 @@ static int vidtv_start_feed(struct dvb_demux_feed *feed) { struct dvb_demux *demux = feed->demux; struct vidtv_dvb *dvb = demux->priv; - int rc; int ret; + int rc; if (!demux->dmx.frontend) return -EINVAL; @@ -251,9 +254,9 @@ static int vidtv_stop_feed(struct dvb_demux_feed *feed) static struct dvb_frontend *vidtv_get_frontend_ptr(struct i2c_client *c) { - /* the demod will set this when its probe function runs */ struct vidtv_demod_state *state = i2c_get_clientdata(c); + /* the demod will set this when its probe function runs */ return &state->frontend; } @@ -261,6 +264,11 @@ static int vidtv_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) { + /* + * Right now, this virtual driver doesn't really send or receive + * messages from I2C. A real driver will require an implementation + * here. + */ return 0; } @@ -328,11 +336,10 @@ static int vidtv_bridge_dmxdev_init(struct vidtv_dvb *dvb) static int vidtv_bridge_probe_demod(struct vidtv_dvb *dvb, u32 n) { - struct vidtv_demod_config cfg = {}; - - cfg.drop_tslock_prob_on_low_snr = drop_tslock_prob_on_low_snr; - cfg.recover_tslock_prob_on_good_snr = recover_tslock_prob_on_good_snr; - + struct vidtv_demod_config cfg = { + .drop_tslock_prob_on_low_snr = drop_tslock_prob_on_low_snr, + .recover_tslock_prob_on_good_snr = recover_tslock_prob_on_good_snr, + }; dvb->i2c_client_demod[n] = dvb_module_probe("dvb_vidtv_demod", NULL, &dvb->i2c_adapter, @@ -351,14 +358,14 @@ static int vidtv_bridge_probe_demod(struct vidtv_dvb *dvb, u32 n) static int vidtv_bridge_probe_tuner(struct vidtv_dvb *dvb, u32 n) { - struct vidtv_tuner_config cfg = {}; + struct vidtv_tuner_config cfg = { + .fe = dvb->fe[n], + .mock_power_up_delay_msec = mock_power_up_delay_msec, + .mock_tune_delay_msec = mock_tune_delay_msec, + }; u32 freq; int i; - cfg.fe = dvb->fe[n]; - cfg.mock_power_up_delay_msec = mock_power_up_delay_msec; - cfg.mock_tune_delay_msec = mock_tune_delay_msec; - /* TODO: check if the frequencies are at a valid range */ memcpy(cfg.vidtv_valid_dvb_t_freqs, @@ -397,9 +404,7 @@ static int vidtv_bridge_probe_tuner(struct vidtv_dvb *dvb, u32 n) static int vidtv_bridge_dvb_init(struct vidtv_dvb *dvb) { - int ret; - int i; - int j; + int ret, i, j; ret = vidtv_bridge_i2c_register_adap(dvb); if (ret < 0) diff --git a/drivers/media/test-drivers/vidtv/vidtv_channel.c b/drivers/media/test-drivers/vidtv/vidtv_channel.c index f64a68dea234..8206bcefd7c7 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_channel.c +++ b/drivers/media/test-drivers/vidtv/vidtv_channel.c @@ -33,8 +33,8 @@ static void vidtv_channel_encoder_destroy(struct vidtv_encoder *e) { - struct vidtv_encoder *curr = e; struct vidtv_encoder *tmp = NULL; + struct vidtv_encoder *curr = e; while (curr) { /* forward the call to the derived type */ @@ -46,25 +46,25 @@ static void vidtv_channel_encoder_destroy(struct vidtv_encoder *e) #define ENCODING_ISO8859_15 "\x0b" +/* + * init an audio only channel with a s302m encoder + */ struct vidtv_channel *vidtv_channel_s302m_init(struct vidtv_channel *head, u16 transport_stream_id) { - /* - * init an audio only channel with a s302m encoder - */ - const u16 s302m_service_id = 0x880; - const u16 s302m_program_num = 0x880; - const u16 s302m_program_pid = 0x101; /* packet id for PMT*/ - const u16 s302m_es_pid = 0x111; /* packet id for the ES */ const __be32 s302m_fid = cpu_to_be32(VIDTV_S302M_FORMAT_IDENTIFIER); - char *name = ENCODING_ISO8859_15 "Beethoven"; - char *provider = ENCODING_ISO8859_15 "LinuxTV.org"; - char *iso_language_code = ENCODING_ISO8859_15 "eng"; - char *event_name = ENCODING_ISO8859_15 "Beethoven Music"; char *event_text = ENCODING_ISO8859_15 "Beethoven's Für Elise"; + char *event_name = ENCODING_ISO8859_15 "Beethoven Music"; + struct vidtv_s302m_encoder_init_args encoder_args = {}; + char *iso_language_code = ENCODING_ISO8859_15 "eng"; + char *provider = ENCODING_ISO8859_15 "LinuxTV.org"; + char *name = ENCODING_ISO8859_15 "Beethoven"; + const u16 s302m_es_pid = 0x111; /* packet id for the ES */ + const u16 s302m_program_pid = 0x101; /* packet id for PMT*/ + const u16 s302m_service_id = 0x880; + const u16 s302m_program_num = 0x880; const u16 s302m_beethoven_event_id = 1; struct vidtv_channel *s302m; - struct vidtv_s302m_encoder_init_args encoder_args = {}; s302m = kzalloc(sizeof(*s302m), GFP_KERNEL); if (!s302m) @@ -159,11 +159,9 @@ static struct vidtv_psi_table_eit_event { /* Concatenate the events */ const struct vidtv_channel *cur_chnl = m->channels; - struct vidtv_psi_table_eit_event *curr = NULL; struct vidtv_psi_table_eit_event *head = NULL; struct vidtv_psi_table_eit_event *tail = NULL; - struct vidtv_psi_desc *desc = NULL; u16 event_id; @@ -175,7 +173,8 @@ static struct vidtv_psi_table_eit_event if (!curr) dev_warn_ratelimited(m->dev, - "No events found for channel %s\n", cur_chnl->name); + "No events found for channel %s\n", + cur_chnl->name); while (curr) { event_id = be16_to_cpu(curr->event_id); @@ -221,7 +220,8 @@ static struct vidtv_psi_table_sdt_service if (!curr) dev_warn_ratelimited(m->dev, - "No services found for channel %s\n", cur_chnl->name); + "No services found for channel %s\n", + cur_chnl->name); while (curr) { service_id = be16_to_cpu(curr->service_id); @@ -300,26 +300,24 @@ vidtv_channel_pat_prog_cat_into_new(struct vidtv_mux *m) return head; } +/* + * Match channels to their respective PMT sections, then assign the + * streams + */ static void vidtv_channel_pmt_match_sections(struct vidtv_channel *channels, struct vidtv_psi_table_pmt **sections, u32 nsections) { - /* - * Match channels to their respective PMT sections, then assign the - * streams - */ struct vidtv_psi_table_pmt *curr_section = NULL; - struct vidtv_channel *cur_chnl = channels; - - struct vidtv_psi_table_pmt_stream *s = NULL; struct vidtv_psi_table_pmt_stream *head = NULL; struct vidtv_psi_table_pmt_stream *tail = NULL; - + struct vidtv_psi_table_pmt_stream *s = NULL; + struct vidtv_channel *cur_chnl = channels; struct vidtv_psi_desc *desc = NULL; - u32 j; - u16 curr_id; u16 e_pid; /* elementary stream pid */ + u16 curr_id; + u32 j; while (cur_chnl) { for (j = 0; j < nsections; ++j) { @@ -345,7 +343,8 @@ vidtv_channel_pmt_match_sections(struct vidtv_channel *channels, head = tail; desc = vidtv_psi_desc_clone(s->descriptor); - vidtv_psi_desc_assign(&tail->descriptor, desc); + vidtv_psi_desc_assign(&tail->descriptor, + desc); s = s->next; } @@ -359,7 +358,8 @@ vidtv_channel_pmt_match_sections(struct vidtv_channel *channels, } } -static void vidtv_channel_destroy_service_list(struct vidtv_psi_desc_service_list_entry *e) +static void +vidtv_channel_destroy_service_list(struct vidtv_psi_desc_service_list_entry *e) { struct vidtv_psi_desc_service_list_entry *tmp; @@ -412,9 +412,9 @@ next_desc: int vidtv_channel_si_init(struct vidtv_mux *m) { + struct vidtv_psi_desc_service_list_entry *service_list = NULL; struct vidtv_psi_table_pat_program *programs = NULL; struct vidtv_psi_table_sdt_service *services = NULL; - struct vidtv_psi_desc_service_list_entry *service_list = NULL; struct vidtv_psi_table_eit_event *events = NULL; m->si.pat = vidtv_psi_pat_table_init(m->transport_stream_id); @@ -449,11 +449,11 @@ int vidtv_channel_si_init(struct vidtv_mux *m) if (!m->si.nit) goto free_service_list; - m->si.eit = vidtv_psi_eit_table_init(m->network_id, m->transport_stream_id); + m->si.eit = vidtv_psi_eit_table_init(m->network_id, + m->transport_stream_id); if (!m->si.eit) goto free_nit; - /* assemble all programs and assign to PAT */ vidtv_psi_pat_program_assign(m->si.pat, programs); @@ -463,7 +463,8 @@ int vidtv_channel_si_init(struct vidtv_mux *m) /* assemble all events and assign to EIT */ vidtv_psi_eit_event_assign(m->si.eit, events); - m->si.pmt_secs = vidtv_psi_pmt_create_sec_for_each_pat_entry(m->si.pat, m->pcr_pid); + m->si.pmt_secs = vidtv_psi_pmt_create_sec_for_each_pat_entry(m->si.pat, + m->pcr_pid); if (!m->si.pmt_secs) goto free_eit; @@ -496,8 +497,8 @@ free_pat: void vidtv_channel_si_destroy(struct vidtv_mux *m) { - u32 i; u16 num_programs = m->si.pat->programs; + u32 i; vidtv_psi_pat_table_destroy(m->si.pat); diff --git a/drivers/media/test-drivers/vidtv/vidtv_demod.c b/drivers/media/test-drivers/vidtv/vidtv_demod.c index 63ac55b81f39..b7823d97b30d 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_demod.c +++ b/drivers/media/test-drivers/vidtv/vidtv_demod.c @@ -193,7 +193,6 @@ static void vidtv_demod_update_stats(struct dvb_frontend *fe) c->cnr.stat[0].svalue = state->tuner_cnr; c->cnr.stat[0].svalue -= prandom_u32_max(state->tuner_cnr / 50); - } static int vidtv_demod_read_status(struct dvb_frontend *fe, diff --git a/drivers/media/test-drivers/vidtv/vidtv_encoder.h b/drivers/media/test-drivers/vidtv/vidtv_encoder.h index f742d566fbcb..0ac5b1e3f666 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_encoder.h +++ b/drivers/media/test-drivers/vidtv/vidtv_encoder.h @@ -28,7 +28,7 @@ struct vidtv_access_unit { struct vidtv_access_unit *next; }; -/* Some musical notes, used by a tone generator */ +/* Some musical notes, used by a tone generator. Values are in Hz */ enum musical_notes { NOTE_SILENT = 0, diff --git a/drivers/media/test-drivers/vidtv/vidtv_mux.c b/drivers/media/test-drivers/vidtv/vidtv_mux.c index eb24e27b7f5f..6df9cfd7f33b 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_mux.c +++ b/drivers/media/test-drivers/vidtv/vidtv_mux.c @@ -63,9 +63,9 @@ static struct vidtv_mux_pid_ctx static void vidtv_mux_pid_ctx_destroy(struct vidtv_mux *m) { - int bkt; struct vidtv_mux_pid_ctx *ctx; struct hlist_node *tmp; + int bkt; hash_for_each_safe(m->pid_ctx, bkt, tmp, ctx, h) { hash_del(&ctx->h); @@ -129,21 +129,18 @@ static void vidtv_mux_update_clk(struct vidtv_mux *m) static u32 vidtv_mux_push_si(struct vidtv_mux *m) { + struct vidtv_psi_pat_write_args pat_args = {}; + struct vidtv_psi_pmt_write_args pmt_args = {}; + struct vidtv_psi_sdt_write_args sdt_args = {}; + struct vidtv_psi_nit_write_args nit_args = {}; + struct vidtv_psi_eit_write_args eit_args = {}; u32 initial_offset = m->mux_buf_offset; - struct vidtv_mux_pid_ctx *pat_ctx; struct vidtv_mux_pid_ctx *pmt_ctx; struct vidtv_mux_pid_ctx *sdt_ctx; struct vidtv_mux_pid_ctx *nit_ctx; struct vidtv_mux_pid_ctx *eit_ctx; - - struct vidtv_psi_pat_write_args pat_args = {}; - struct vidtv_psi_pmt_write_args pmt_args = {}; - struct vidtv_psi_sdt_write_args sdt_args = {}; - struct vidtv_psi_nit_write_args nit_args = {}; - struct vidtv_psi_eit_write_args eit_args = {}; - - u32 nbytes; /* the number of bytes written by this function */ + u32 nbytes; u16 pmt_pid; u32 i; @@ -269,7 +266,6 @@ static bool vidtv_mux_should_push_si(struct vidtv_mux *m) static u32 vidtv_mux_packetize_access_units(struct vidtv_mux *m, struct vidtv_encoder *e) { - u32 nbytes = 0; struct pes_write_args args = { .dest_buf = m->mux_buf, .dest_buf_sz = m->mux_buf_sz, @@ -279,10 +275,11 @@ static u32 vidtv_mux_packetize_access_units(struct vidtv_mux *m, .send_pts = true, /* forbidden value '01'... */ .send_dts = false, /* ...for PTS_DTS flags */ }; - u32 initial_offset = m->mux_buf_offset; struct vidtv_access_unit *au = e->access_units; - u8 *buf = NULL; + u32 initial_offset = m->mux_buf_offset; struct vidtv_mux_pid_ctx *pid_ctx; + u32 nbytes = 0; + u8 *buf = NULL; /* see SMPTE 302M clause 6.4 */ if (args.encoder_id == S302M) { @@ -318,10 +315,10 @@ static u32 vidtv_mux_packetize_access_units(struct vidtv_mux *m, static u32 vidtv_mux_poll_encoders(struct vidtv_mux *m) { - u32 nbytes = 0; - u32 au_nbytes; struct vidtv_channel *cur_chnl = m->channels; struct vidtv_encoder *e = NULL; + u32 nbytes = 0; + u32 au_nbytes; while (cur_chnl) { e = cur_chnl->encoders; @@ -347,9 +344,9 @@ static u32 vidtv_mux_pad_with_nulls(struct vidtv_mux *m, u32 npkts) { struct null_packet_write_args args = {}; u32 initial_offset = m->mux_buf_offset; - u32 nbytes; /* the number of bytes written by this function */ - u32 i; struct vidtv_mux_pid_ctx *ctx; + u32 nbytes; + u32 i; ctx = vidtv_mux_get_pid_ctx(m, TS_NULL_PACKET_PID); @@ -388,9 +385,9 @@ static void vidtv_mux_tick(struct work_struct *work) struct vidtv_mux, mpeg_thread); struct dtv_frontend_properties *c = &m->fe->dtv_property_cache; + u32 tot_bits = 0; u32 nbytes; u32 npkts; - u32 tot_bits = 0; while (m->streaming) { nbytes = 0; diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c index b31a29f46bde..375e01480d3d 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.c +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c @@ -76,7 +76,7 @@ static const u32 CRC_LUT[256] = { 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 }; -static inline u32 dvb_crc32(u32 crc, u8 *data, u32 len) +static u32 dvb_crc32(u32 crc, u8 *data, u32 len) { /* from libdvbv5 */ while (len--) @@ -89,7 +89,8 @@ static void vidtv_psi_update_version_num(struct vidtv_psi_table_header *h) h->version++; } -static inline u16 vidtv_psi_sdt_serv_get_desc_loop_len(struct vidtv_psi_table_sdt_service *s) +static u16 +vidtv_psi_sdt_serv_get_desc_loop_len(struct vidtv_psi_table_sdt_service *s) { u16 mask; u16 ret; @@ -100,7 +101,8 @@ static inline u16 vidtv_psi_sdt_serv_get_desc_loop_len(struct vidtv_psi_table_sd return ret; } -static inline u16 vidtv_psi_pmt_stream_get_desc_loop_len(struct vidtv_psi_table_pmt_stream *s) +static u16 +vidtv_psi_pmt_stream_get_desc_loop_len(struct vidtv_psi_table_pmt_stream *s) { u16 mask; u16 ret; @@ -111,7 +113,7 @@ static inline u16 vidtv_psi_pmt_stream_get_desc_loop_len(struct vidtv_psi_table_ return ret; } -static inline u16 vidtv_psi_pmt_get_desc_loop_len(struct vidtv_psi_table_pmt *p) +static u16 vidtv_psi_pmt_get_desc_loop_len(struct vidtv_psi_table_pmt *p) { u16 mask; u16 ret; @@ -122,7 +124,7 @@ static inline u16 vidtv_psi_pmt_get_desc_loop_len(struct vidtv_psi_table_pmt *p) return ret; } -static inline u16 vidtv_psi_get_sec_len(struct vidtv_psi_table_header *h) +static u16 vidtv_psi_get_sec_len(struct vidtv_psi_table_header *h) { u16 mask; u16 ret; @@ -133,7 +135,7 @@ static inline u16 vidtv_psi_get_sec_len(struct vidtv_psi_table_header *h) return ret; } -inline u16 vidtv_psi_get_pat_program_pid(struct vidtv_psi_table_pat_program *p) +u16 vidtv_psi_get_pat_program_pid(struct vidtv_psi_table_pat_program *p) { u16 mask; u16 ret; @@ -144,7 +146,7 @@ inline u16 vidtv_psi_get_pat_program_pid(struct vidtv_psi_table_pat_program *p) return ret; } -inline u16 vidtv_psi_pmt_stream_get_elem_pid(struct vidtv_psi_table_pmt_stream *s) +u16 vidtv_psi_pmt_stream_get_elem_pid(struct vidtv_psi_table_pmt_stream *s) { u16 mask; u16 ret; @@ -155,10 +157,11 @@ inline u16 vidtv_psi_pmt_stream_get_elem_pid(struct vidtv_psi_table_pmt_stream * return ret; } -static inline void vidtv_psi_set_desc_loop_len(__be16 *bitfield, u16 new_len, u8 desc_len_nbits) +static void vidtv_psi_set_desc_loop_len(__be16 *bitfield, u16 new_len, + u8 desc_len_nbits) { - u16 mask; __be16 new; + u16 mask; mask = GENMASK(15, desc_len_nbits); @@ -185,27 +188,22 @@ static void vidtv_psi_set_sec_len(struct vidtv_psi_table_header *h, u16 new_len) h->bitfield = new; } +/* + * Packetize PSI sections into TS packets: + * push a TS header (4bytes) every 184 bytes + * manage the continuity_counter + * add stuffing (i.e. padding bytes) after the CRC + */ static u32 vidtv_psi_ts_psi_write_into(struct psi_write_args args) { - /* - * Packetize PSI sections into TS packets: - * push a TS header (4bytes) every 184 bytes - * manage the continuity_counter - * add stuffing (i.e. padding bytes) after the CRC - */ u32 nbytes_past_boundary = (args.dest_offset % TS_PACKET_LEN); bool aligned = (nbytes_past_boundary == 0); struct vidtv_mpeg_ts ts_header = {}; - - /* number of bytes written by this function */ - u32 nbytes = 0; - /* how much there is left to write */ u32 remaining_len = args.len; - /* how much we can be written in this packet */ u32 payload_write_len = 0; - /* where we are in the source */ u32 payload_offset = 0; + u32 nbytes = 0; const u16 PAYLOAD_START = args.new_psi_section; @@ -294,9 +292,10 @@ static u32 vidtv_psi_ts_psi_write_into(struct psi_write_args args) static u32 table_section_crc32_write_into(struct crc32_write_args args) { - /* the CRC is the last entry in the section */ - u32 nbytes = 0; struct psi_write_args psi_args = {}; + u32 nbytes = 0; + + /* the CRC is the last entry in the section */ psi_args.dest_buf = args.dest_buf; psi_args.from = &args.crc; @@ -391,8 +390,8 @@ struct vidtv_psi_desc_registration struct vidtv_psi_desc_network_name *vidtv_psi_network_name_desc_init(struct vidtv_psi_desc *head, char *network_name) { - struct vidtv_psi_desc_network_name *desc; u32 network_name_len = network_name ? strlen(network_name) : 0; + struct vidtv_psi_desc_network_name *desc; desc = kzalloc(sizeof(*desc), GFP_KERNEL); if (!desc) @@ -413,10 +412,10 @@ struct vidtv_psi_desc_service_list *vidtv_psi_service_list_desc_init(struct vidtv_psi_desc *head, struct vidtv_psi_desc_service_list_entry *entry) { - struct vidtv_psi_desc_service_list *desc; struct vidtv_psi_desc_service_list_entry *curr_e = NULL; struct vidtv_psi_desc_service_list_entry *head_e = NULL; struct vidtv_psi_desc_service_list_entry *prev_e = NULL; + struct vidtv_psi_desc_service_list *desc; u16 length = 0; desc = kzalloc(sizeof(*desc), GFP_KERNEL); @@ -465,10 +464,10 @@ struct vidtv_psi_desc_short_event char *event_name, char *text) { - struct vidtv_psi_desc_short_event *desc; + u32 iso_len = iso_language_code ? strlen(iso_language_code) : 0; u32 event_name_len = event_name ? strlen(event_name) : 0; + struct vidtv_psi_desc_short_event *desc; u32 text_len = text ? strlen(text) : 0; - u32 iso_len = iso_language_code ? strlen(iso_language_code) : 0; desc = kzalloc(sizeof(*desc), GFP_KERNEL); if (!desc) @@ -502,14 +501,13 @@ struct vidtv_psi_desc_short_event struct vidtv_psi_desc *vidtv_psi_desc_clone(struct vidtv_psi_desc *desc) { - struct vidtv_psi_desc *head = NULL; - struct vidtv_psi_desc *prev = NULL; - struct vidtv_psi_desc *curr = NULL; - - struct vidtv_psi_desc_service *service; struct vidtv_psi_desc_network_name *desc_network_name; struct vidtv_psi_desc_service_list *desc_service_list; struct vidtv_psi_desc_short_event *desc_short_event; + struct vidtv_psi_desc_service *service; + struct vidtv_psi_desc *head = NULL; + struct vidtv_psi_desc *prev = NULL; + struct vidtv_psi_desc *curr = NULL; while (desc) { switch (desc->type) { @@ -571,10 +569,10 @@ struct vidtv_psi_desc *vidtv_psi_desc_clone(struct vidtv_psi_desc *desc) void vidtv_psi_desc_destroy(struct vidtv_psi_desc *desc) { + struct vidtv_psi_desc_service_list_entry *sl_entry_tmp = NULL; + struct vidtv_psi_desc_service_list_entry *sl_entry = NULL; struct vidtv_psi_desc *curr = desc; struct vidtv_psi_desc *tmp = NULL; - struct vidtv_psi_desc_service_list_entry *sl_entry = NULL; - struct vidtv_psi_desc_service_list_entry *sl_entry_tmp = NULL; while (curr) { tmp = curr; @@ -677,10 +675,10 @@ void vidtv_sdt_desc_assign(struct vidtv_psi_table_sdt *sdt, static u32 vidtv_psi_desc_write_into(struct desc_write_args args) { + struct vidtv_psi_desc_service_list_entry *serv_list_entry = NULL; + struct psi_write_args psi_args = {}; /* the number of bytes written by this function */ u32 nbytes = 0; - struct psi_write_args psi_args = {}; - struct vidtv_psi_desc_service_list_entry *serv_list_entry = NULL; psi_args.dest_buf = args.dest_buf; psi_args.from = &args.desc->type; @@ -799,9 +797,9 @@ static u32 vidtv_psi_desc_write_into(struct desc_write_args args) static u32 vidtv_psi_table_header_write_into(struct header_write_args args) { + struct psi_write_args psi_args = {}; /* the number of bytes written by this function */ u32 nbytes = 0; - struct psi_write_args psi_args = {}; psi_args.dest_buf = args.dest_buf; psi_args.from = args.h; @@ -822,10 +820,11 @@ vidtv_psi_table_header_write_into(struct header_write_args args) void vidtv_psi_pat_table_update_sec_len(struct vidtv_psi_table_pat *pat) { - /* see ISO/IEC 13818-1 : 2000 p.43 */ u16 length = 0; u32 i; + /* see ISO/IEC 13818-1 : 2000 p.43 */ + /* from immediately after 'section_length' until 'last_section_number'*/ length += PAT_LEN_UNTIL_LAST_SECTION_NUMBER; @@ -841,10 +840,11 @@ vidtv_psi_pat_table_update_sec_len(struct vidtv_psi_table_pat *pat) void vidtv_psi_pmt_table_update_sec_len(struct vidtv_psi_table_pmt *pmt) { - /* see ISO/IEC 13818-1 : 2000 p.46 */ - u16 length = 0; struct vidtv_psi_table_pmt_stream *s = pmt->stream; u16 desc_loop_len; + u16 length = 0; + + /* see ISO/IEC 13818-1 : 2000 p.46 */ /* from immediately after 'section_length' until 'program_info_length'*/ length += PMT_LEN_UNTIL_PROGRAM_INFO_LENGTH; @@ -875,10 +875,11 @@ void vidtv_psi_pmt_table_update_sec_len(struct vidtv_psi_table_pmt *pmt) void vidtv_psi_sdt_table_update_sec_len(struct vidtv_psi_table_sdt *sdt) { - /* see ETSI EN 300 468 V 1.10.1 p.24 */ - u16 length = 0; struct vidtv_psi_table_sdt_service *s = sdt->service; u16 desc_loop_len; + u16 length = 0; + + /* see ETSI EN 300 468 V 1.10.1 p.24 */ /* * from immediately after 'section_length' until @@ -935,8 +936,8 @@ vidtv_psi_pat_program_init(struct vidtv_psi_table_pat_program *head, void vidtv_psi_pat_program_destroy(struct vidtv_psi_table_pat_program *p) { - struct vidtv_psi_table_pat_program *curr = p; struct vidtv_psi_table_pat_program *tmp = NULL; + struct vidtv_psi_table_pat_program *curr = p; while (curr) { tmp = curr; @@ -945,14 +946,13 @@ vidtv_psi_pat_program_destroy(struct vidtv_psi_table_pat_program *p) } } +/* This function transfers ownership of p to the table */ void vidtv_psi_pat_program_assign(struct vidtv_psi_table_pat *pat, struct vidtv_psi_table_pat_program *p) { - /* This function transfers ownership of p to the table */ - - u16 program_count; struct vidtv_psi_table_pat_program *program; + u16 program_count; do { program_count = 0; @@ -1010,16 +1010,13 @@ struct vidtv_psi_table_pat *vidtv_psi_pat_table_init(u16 transport_stream_id) u32 vidtv_psi_pat_write_into(struct vidtv_psi_pat_write_args args) { - /* the number of bytes written by this function */ - u32 nbytes = 0; - const u16 pat_pid = VIDTV_PAT_PID; - u32 crc = INITIAL_CRC; - struct vidtv_psi_table_pat_program *p = args.pat->program; - struct header_write_args h_args = {}; - struct psi_write_args psi_args = {}; + struct psi_write_args psi_args = {}; struct crc32_write_args c_args = {}; + const u16 pat_pid = VIDTV_PAT_PID; + u32 crc = INITIAL_CRC; + u32 nbytes = 0; vidtv_psi_pat_table_update_sec_len(args.pat); @@ -1114,8 +1111,8 @@ vidtv_psi_pmt_stream_init(struct vidtv_psi_table_pmt_stream *head, void vidtv_psi_pmt_stream_destroy(struct vidtv_psi_table_pmt_stream *s) { - struct vidtv_psi_table_pmt_stream *curr_stream = s; struct vidtv_psi_table_pmt_stream *tmp_stream = NULL; + struct vidtv_psi_table_pmt_stream *curr_stream = s; while (curr_stream) { tmp_stream = curr_stream; @@ -1166,11 +1163,11 @@ struct vidtv_psi_table_pmt *vidtv_psi_pmt_table_init(u16 program_number, u16 pcr_pid) { struct vidtv_psi_table_pmt *pmt; - const u16 SYNTAX = 0x1; - const u16 ZERO = 0x0; - const u16 ONES = 0x03; const u16 RESERVED1 = 0x07; const u16 RESERVED2 = 0x0f; + const u16 SYNTAX = 0x1; + const u16 ONES = 0x03; + const u16 ZERO = 0x0; u16 desc_loop_len; pmt = kzalloc(sizeof(*pmt), GFP_KERNEL); @@ -1208,18 +1205,15 @@ struct vidtv_psi_table_pmt *vidtv_psi_pmt_table_init(u16 program_number, u32 vidtv_psi_pmt_write_into(struct vidtv_psi_pmt_write_args args) { - /* the number of bytes written by this function */ - u32 nbytes = 0; - u32 crc = INITIAL_CRC; - struct vidtv_psi_desc *table_descriptor = args.pmt->descriptor; struct vidtv_psi_table_pmt_stream *stream = args.pmt->stream; struct vidtv_psi_desc *stream_descriptor; - struct header_write_args h_args = {}; struct psi_write_args psi_args = {}; struct desc_write_args d_args = {}; struct crc32_write_args c_args = {}; + u32 crc = INITIAL_CRC; + u32 nbytes = 0; vidtv_psi_pmt_table_update_sec_len(args.pmt); @@ -1317,10 +1311,10 @@ void vidtv_psi_pmt_table_destroy(struct vidtv_psi_table_pmt *pmt) struct vidtv_psi_table_sdt *vidtv_psi_sdt_table_init(u16 transport_stream_id) { struct vidtv_psi_table_sdt *sdt; + const u16 RESERVED = 0xff; const u16 SYNTAX = 0x1; - const u16 ONE = 0x1; const u16 ONES = 0x03; - const u16 RESERVED = 0xff; + const u16 ONE = 0x1; sdt = kzalloc(sizeof(*sdt), GFP_KERNEL); if (!sdt) @@ -1360,18 +1354,17 @@ struct vidtv_psi_table_sdt *vidtv_psi_sdt_table_init(u16 transport_stream_id) u32 vidtv_psi_sdt_write_into(struct vidtv_psi_sdt_write_args args) { - u32 nbytes = 0; - u16 sdt_pid = VIDTV_SDT_PID; /* see ETSI EN 300 468 v1.15.1 p. 11 */ - - u32 crc = INITIAL_CRC; - struct vidtv_psi_table_sdt_service *service = args.sdt->service; struct vidtv_psi_desc *service_desc; - struct header_write_args h_args = {}; struct psi_write_args psi_args = {}; struct desc_write_args d_args = {}; struct crc32_write_args c_args = {}; + u16 sdt_pid = VIDTV_SDT_PID; + u32 nbytes = 0; + u32 crc = INITIAL_CRC; + + /* see ETSI EN 300 468 v1.15.1 p. 11 */ vidtv_psi_sdt_table_update_sec_len(args.sdt); @@ -1520,15 +1513,16 @@ vidtv_psi_sdt_service_assign(struct vidtv_psi_table_sdt *sdt, vidtv_psi_update_version_num(&sdt->header); } +/* + * PMTs contain information about programs. For each program, + * there is one PMT section. This function will create a section + * for each program found in the PAT + */ struct vidtv_psi_table_pmt** -vidtv_psi_pmt_create_sec_for_each_pat_entry(struct vidtv_psi_table_pat *pat, u16 pcr_pid) +vidtv_psi_pmt_create_sec_for_each_pat_entry(struct vidtv_psi_table_pat *pat, + u16 pcr_pid) { - /* - * PMTs contain information about programs. For each program, - * there is one PMT section. This function will create a section - * for each program found in the PAT - */ struct vidtv_psi_table_pat_program *program = pat->program; struct vidtv_psi_table_pmt **pmt_secs; u32 i = 0; @@ -1549,12 +1543,12 @@ vidtv_psi_pmt_create_sec_for_each_pat_entry(struct vidtv_psi_table_pat *pat, u16 return pmt_secs; } +/* find the PMT section associated with 'program_num' */ struct vidtv_psi_table_pmt *vidtv_psi_find_pmt_sec(struct vidtv_psi_table_pmt **pmt_sections, u16 nsections, u16 program_num) { - /* find the PMT section associated with 'program_num' */ struct vidtv_psi_table_pmt *sec = NULL; u32 i; @@ -1616,11 +1610,11 @@ struct vidtv_psi_table_nit char *network_name, struct vidtv_psi_desc_service_list_entry *service_list) { - struct vidtv_psi_table_nit *nit; struct vidtv_psi_table_transport *transport; + struct vidtv_psi_table_nit *nit; const u16 SYNTAX = 0x1; - const u16 ONE = 0x1; const u16 ONES = 0x03; + const u16 ONE = 0x1; nit = kzalloc(sizeof(*nit), GFP_KERNEL); if (!nit) @@ -1677,18 +1671,15 @@ free_nit: u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args args) { - /* the number of bytes written by this function */ - u32 nbytes = 0; - u32 crc = INITIAL_CRC; - struct vidtv_psi_desc *table_descriptor = args.nit->descriptor; struct vidtv_psi_table_transport *transport = args.nit->transport; struct vidtv_psi_desc *transport_descriptor; - struct header_write_args h_args = {}; struct psi_write_args psi_args = {}; struct desc_write_args d_args = {}; struct crc32_write_args c_args = {}; + u32 crc = INITIAL_CRC; + u32 nbytes = 0; vidtv_psi_nit_table_update_sec_len(args.nit); @@ -1786,8 +1777,8 @@ u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args args) static void vidtv_psi_transport_destroy(struct vidtv_psi_table_transport *t) { - struct vidtv_psi_table_transport *curr_t = t; struct vidtv_psi_table_transport *tmp_t = NULL; + struct vidtv_psi_table_transport *curr_t = t; while (curr_t) { tmp_t = curr_t; @@ -1806,9 +1797,9 @@ void vidtv_psi_nit_table_destroy(struct vidtv_psi_table_nit *nit) void vidtv_psi_eit_table_update_sec_len(struct vidtv_psi_table_eit *eit) { - u16 length = 0; struct vidtv_psi_table_eit_event *e = eit->event; u16 desc_loop_len; + u16 length = 0; /* * from immediately after 'section_length' until @@ -1890,16 +1881,14 @@ struct vidtv_psi_table_eit u32 vidtv_psi_eit_write_into(struct vidtv_psi_eit_write_args args) { - u32 nbytes = 0; - u32 crc = INITIAL_CRC; - struct vidtv_psi_table_eit_event *event = args.eit->event; struct vidtv_psi_desc *event_descriptor; - struct header_write_args h_args = {}; struct psi_write_args psi_args = {}; struct desc_write_args d_args = {}; struct crc32_write_args c_args = {}; + u32 crc = INITIAL_CRC; + u32 nbytes = 0; vidtv_psi_eit_table_update_sec_len(args.eit); @@ -1978,8 +1967,8 @@ u32 vidtv_psi_eit_write_into(struct vidtv_psi_eit_write_args args) struct vidtv_psi_table_eit_event *vidtv_psi_eit_event_init(struct vidtv_psi_table_eit_event *head, u16 event_id) { - struct vidtv_psi_table_eit_event *e; const u8 DURATION_ONE_HOUR[] = {1, 0, 0}; + struct vidtv_psi_table_eit_event *e; e = kzalloc(sizeof(*e), GFP_KERNEL); if (!e) @@ -2003,8 +1992,8 @@ struct vidtv_psi_table_eit_event void vidtv_psi_eit_event_destroy(struct vidtv_psi_table_eit_event *e) { - struct vidtv_psi_table_eit_event *curr_e = e; struct vidtv_psi_table_eit_event *tmp_e = NULL; + struct vidtv_psi_table_eit_event *curr_e = e; while (curr_e) { tmp_e = curr_e; diff --git a/drivers/media/test-drivers/vidtv/vidtv_s302m.c b/drivers/media/test-drivers/vidtv/vidtv_s302m.c index 569e7a50129f..ce7dd6cafc8b 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_s302m.c +++ b/drivers/media/test-drivers/vidtv/vidtv_s302m.c @@ -201,10 +201,10 @@ static void vidtv_s302m_alloc_au(struct vidtv_encoder *e) static void vidtv_s302m_compute_sample_count_from_video(struct vidtv_encoder *e) { - struct vidtv_access_unit *au = e->access_units; struct vidtv_access_unit *sync_au = e->sync->access_units; - u32 vau_duration_usecs; + struct vidtv_access_unit *au = e->access_units; u32 sample_duration_usecs; + u32 vau_duration_usecs; u32 s; vau_duration_usecs = USEC_PER_SEC / e->sync->sampling_rate_hz; @@ -290,9 +290,9 @@ static u16 vidtv_s302m_get_sample(struct vidtv_encoder *e) static u32 vidtv_s302m_write_frame(struct vidtv_encoder *e, u16 sample) { - u32 nbytes = 0; - struct vidtv_s302m_frame_16 f = {}; struct vidtv_s302m_ctx *ctx = e->ctx; + struct vidtv_s302m_frame_16 f = {}; + u32 nbytes = 0; /* from ffmpeg: see s302enc.c */ @@ -389,6 +389,8 @@ static void vidtv_s302m_write_frames(struct vidtv_encoder *e) static void *vidtv_s302m_encode(struct vidtv_encoder *e) { + struct vidtv_s302m_ctx *ctx = e->ctx; + /* * According to SMPTE 302M, an audio access unit is specified as those * AES3 words that are associated with a corresponding video frame. @@ -402,8 +404,6 @@ static void *vidtv_s302m_encode(struct vidtv_encoder *e) * ffmpeg */ - struct vidtv_s302m_ctx *ctx = e->ctx; - vidtv_s302m_access_unit_destroy(e); vidtv_s302m_alloc_au(e); @@ -441,9 +441,9 @@ static u32 vidtv_s302m_clear(struct vidtv_encoder *e) struct vidtv_encoder *vidtv_s302m_encoder_init(struct vidtv_s302m_encoder_init_args args) { - struct vidtv_encoder *e; u32 priv_sz = sizeof(struct vidtv_s302m_ctx); struct vidtv_s302m_ctx *ctx; + struct vidtv_encoder *e; e = kzalloc(sizeof(*e), GFP_KERNEL); if (!e) -- cgit v1.2.3 From 330d135679e55659448953c80753c33ef16383aa Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 20 Nov 2020 09:39:03 +0100 Subject: media: vidtv: remove some unused functions Right now, there's no need to access the length of some tables. So, drop the unused functions. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_psi.c | 35 ---------------------------- 1 file changed, 35 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c index 375e01480d3d..341af312ad56 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.c +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c @@ -89,41 +89,6 @@ static void vidtv_psi_update_version_num(struct vidtv_psi_table_header *h) h->version++; } -static u16 -vidtv_psi_sdt_serv_get_desc_loop_len(struct vidtv_psi_table_sdt_service *s) -{ - u16 mask; - u16 ret; - - mask = GENMASK(11, 0); - - ret = be16_to_cpu(s->bitfield) & mask; - return ret; -} - -static u16 -vidtv_psi_pmt_stream_get_desc_loop_len(struct vidtv_psi_table_pmt_stream *s) -{ - u16 mask; - u16 ret; - - mask = GENMASK(9, 0); - - ret = be16_to_cpu(s->bitfield2) & mask; - return ret; -} - -static u16 vidtv_psi_pmt_get_desc_loop_len(struct vidtv_psi_table_pmt *p) -{ - u16 mask; - u16 ret; - - mask = GENMASK(9, 0); - - ret = be16_to_cpu(p->bitfield2) & mask; - return ret; -} - static u16 vidtv_psi_get_sec_len(struct vidtv_psi_table_header *h) { u16 mask; -- cgit v1.2.3 From c857b065abf9bd8f2064cbf82c03aba7277fe2e1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 20 Nov 2020 10:51:50 +0100 Subject: media: vidtv: pre-initialize mux arrays Instead of first zeroing all fields at the mux structs and then filling, do some initialization for the const data when they're created. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_mux.c | 46 ++++++++++++++++------------ 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_mux.c b/drivers/media/test-drivers/vidtv/vidtv_mux.c index 6df9cfd7f33b..728ae7c78827 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_mux.c +++ b/drivers/media/test-drivers/vidtv/vidtv_mux.c @@ -129,11 +129,32 @@ static void vidtv_mux_update_clk(struct vidtv_mux *m) static u32 vidtv_mux_push_si(struct vidtv_mux *m) { - struct vidtv_psi_pat_write_args pat_args = {}; - struct vidtv_psi_pmt_write_args pmt_args = {}; - struct vidtv_psi_sdt_write_args sdt_args = {}; - struct vidtv_psi_nit_write_args nit_args = {}; - struct vidtv_psi_eit_write_args eit_args = {}; + struct vidtv_psi_pat_write_args pat_args = { + .buf = m->mux_buf, + .buf_sz = m->mux_buf_sz, + .pat = m->si.pat, + }; + struct vidtv_psi_pmt_write_args pmt_args = { + .buf = m->mux_buf, + .buf_sz = m->mux_buf_sz, + .pcr_pid = m->pcr_pid, + }; + struct vidtv_psi_sdt_write_args sdt_args = { + .buf = m->mux_buf, + .buf_sz = m->mux_buf_sz, + .sdt = m->si.sdt, + }; + struct vidtv_psi_nit_write_args nit_args = { + .buf = m->mux_buf, + .buf_sz = m->mux_buf_sz, + .nit = m->si.nit, + + }; + struct vidtv_psi_eit_write_args eit_args = { + .buf = m->mux_buf, + .buf_sz = m->mux_buf_sz, + .eit = m->si.eit, + }; u32 initial_offset = m->mux_buf_offset; struct vidtv_mux_pid_ctx *pat_ctx; struct vidtv_mux_pid_ctx *pmt_ctx; @@ -149,10 +170,7 @@ static u32 vidtv_mux_push_si(struct vidtv_mux *m) nit_ctx = vidtv_mux_get_pid_ctx(m, VIDTV_NIT_PID); eit_ctx = vidtv_mux_get_pid_ctx(m, VIDTV_EIT_PID); - pat_args.buf = m->mux_buf; pat_args.offset = m->mux_buf_offset; - pat_args.pat = m->si.pat; - pat_args.buf_sz = m->mux_buf_sz; pat_args.continuity_counter = &pat_ctx->cc; m->mux_buf_offset += vidtv_psi_pat_write_into(pat_args); @@ -169,38 +187,26 @@ static u32 vidtv_mux_push_si(struct vidtv_mux *m) pmt_ctx = vidtv_mux_get_pid_ctx(m, pmt_pid); - pmt_args.buf = m->mux_buf; pmt_args.offset = m->mux_buf_offset; pmt_args.pmt = m->si.pmt_secs[i]; pmt_args.pid = pmt_pid; - pmt_args.buf_sz = m->mux_buf_sz; pmt_args.continuity_counter = &pmt_ctx->cc; - pmt_args.pcr_pid = m->pcr_pid; /* write each section into buffer */ m->mux_buf_offset += vidtv_psi_pmt_write_into(pmt_args); } - sdt_args.buf = m->mux_buf; sdt_args.offset = m->mux_buf_offset; - sdt_args.sdt = m->si.sdt; - sdt_args.buf_sz = m->mux_buf_sz; sdt_args.continuity_counter = &sdt_ctx->cc; m->mux_buf_offset += vidtv_psi_sdt_write_into(sdt_args); - nit_args.buf = m->mux_buf; nit_args.offset = m->mux_buf_offset; - nit_args.nit = m->si.nit; - nit_args.buf_sz = m->mux_buf_sz; nit_args.continuity_counter = &nit_ctx->cc; m->mux_buf_offset += vidtv_psi_nit_write_into(nit_args); - eit_args.buf = m->mux_buf; eit_args.offset = m->mux_buf_offset; - eit_args.eit = m->si.eit; - eit_args.buf_sz = m->mux_buf_sz; eit_args.continuity_counter = &eit_ctx->cc; m->mux_buf_offset += vidtv_psi_eit_write_into(eit_args); -- cgit v1.2.3 From ec3eda53f4aec2e1a9cd0df27c12c95e02f8aec0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 20 Nov 2020 11:15:24 +0100 Subject: media: vidtv: cleanup null packet initialization logic Initialize the destination buffer/size and the initial offset when creating the local var. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_mux.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_mux.c b/drivers/media/test-drivers/vidtv/vidtv_mux.c index 728ae7c78827..e0cc74e98632 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_mux.c +++ b/drivers/media/test-drivers/vidtv/vidtv_mux.c @@ -348,7 +348,11 @@ static u32 vidtv_mux_poll_encoders(struct vidtv_mux *m) static u32 vidtv_mux_pad_with_nulls(struct vidtv_mux *m, u32 npkts) { - struct null_packet_write_args args = {}; + struct null_packet_write_args args = { + .dest_buf = m->mux_buf, + .buf_sz = m->mux_buf_sz, + .dest_offset = m->mux_buf_offset, + }; u32 initial_offset = m->mux_buf_offset; struct vidtv_mux_pid_ctx *ctx; u32 nbytes; @@ -356,10 +360,7 @@ static u32 vidtv_mux_pad_with_nulls(struct vidtv_mux *m, u32 npkts) ctx = vidtv_mux_get_pid_ctx(m, TS_NULL_PACKET_PID); - args.dest_buf = m->mux_buf; - args.buf_sz = m->mux_buf_sz; args.continuity_counter = &ctx->cc; - args.dest_offset = m->mux_buf_offset; for (i = 0; i < npkts; ++i) { m->mux_buf_offset += vidtv_ts_null_write_into(args); -- cgit v1.2.3 From b9e09e06e32e61269342e34f41321499da50d428 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 23 Nov 2020 11:24:11 +0100 Subject: media: vidtv: improve EIT data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Place some text at EIT data, and use ISO 8859-15 encoding for the German letter "ü" (u mit umlat) letter. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_channel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_channel.c b/drivers/media/test-drivers/vidtv/vidtv_channel.c index 8206bcefd7c7..b49fb61847e1 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_channel.c +++ b/drivers/media/test-drivers/vidtv/vidtv_channel.c @@ -53,8 +53,8 @@ struct vidtv_channel *vidtv_channel_s302m_init(struct vidtv_channel *head, u16 transport_stream_id) { const __be32 s302m_fid = cpu_to_be32(VIDTV_S302M_FORMAT_IDENTIFIER); - char *event_text = ENCODING_ISO8859_15 "Beethoven's Für Elise"; - char *event_name = ENCODING_ISO8859_15 "Beethoven Music"; + char *event_text = ENCODING_ISO8859_15 "Bagatelle No. 25 in A minor for solo piano, also known as F\xfcr Elise, composed by Ludwig van Beethoven"; + char *event_name = ENCODING_ISO8859_15 "Ludwig van Beethoven: F\xfcr Elise"; struct vidtv_s302m_encoder_init_args encoder_args = {}; char *iso_language_code = ENCODING_ISO8859_15 "eng"; char *provider = ENCODING_ISO8859_15 "LinuxTV.org"; -- cgit v1.2.3 From 1d2b2a6d8c599be2cbb1e984eeb970186694ef38 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 23 Nov 2020 12:20:45 +0100 Subject: media: vidtv: fix the network ID range As defined at ETSI TS 101 162, original network IDs up to 0xfebf are reserved for registration at dvb.org. Let's use, instead, an original network ID at the range 0xff00-0xffff, as this is for private temporary usage. As the same value is also used for the network ID, the range 0xff01-0xffff also fits better, as values lower than that depend if the network is used for satellite, terrestrial, cable of CI. While here, move the TS ID to the bridge code, where it is used, and change its value, as it was identical to the value previously used by network ID. While we could keep the same value, let's change it, just to make easier to check for the new code while reading it with DVB tools like dvbinspector. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_bridge.c | 3 ++- drivers/media/test-drivers/vidtv/vidtv_common.h | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_bridge.c b/drivers/media/test-drivers/vidtv/vidtv_bridge.c index d428bdb47ae4..fc64d0c8492a 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_bridge.c +++ b/drivers/media/test-drivers/vidtv/vidtv_bridge.c @@ -29,8 +29,9 @@ #define MUX_BUF_MAX_SZ (MUX_BUF_MIN_SZ * 10) #define TUNER_DEFAULT_ADDR 0x68 #define DEMOD_DEFAULT_ADDR 0x60 -#define VIDTV_DEFAULT_NETWORK_ID 0x744 +#define VIDTV_DEFAULT_NETWORK_ID 0xff44 #define VIDTV_DEFAULT_NETWORK_NAME "LinuxTV.org" +#define VIDTV_DEFAULT_TS_ID 0x4081 /* * The LNBf fake parameters here are the ranges used by an diff --git a/drivers/media/test-drivers/vidtv/vidtv_common.h b/drivers/media/test-drivers/vidtv/vidtv_common.h index 818e7f2b9ec5..42f63fdee681 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_common.h +++ b/drivers/media/test-drivers/vidtv/vidtv_common.h @@ -16,7 +16,6 @@ #define CLOCK_UNIT_27MHZ 27000000 #define VIDTV_SLEEP_USECS 10000 #define VIDTV_MAX_SLEEP_USECS (2 * VIDTV_SLEEP_USECS) -#define VIDTV_DEFAULT_TS_ID 0x744 u32 vidtv_memcpy(void *to, size_t to_offset, -- cgit v1.2.3 From 91a8a240e2806c37eaf730347831f4a7de1535ac Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 23 Nov 2020 13:51:31 +0100 Subject: media: vidtv: properly fill EIT service_id The EIT header ID field should not contain the network ID, but, instead, the service_id of the program described at EIT. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_channel.c | 3 ++- drivers/media/test-drivers/vidtv/vidtv_psi.c | 5 +++-- drivers/media/test-drivers/vidtv/vidtv_psi.h | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_channel.c b/drivers/media/test-drivers/vidtv/vidtv_channel.c index b49fb61847e1..77e33f33afee 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_channel.c +++ b/drivers/media/test-drivers/vidtv/vidtv_channel.c @@ -450,7 +450,8 @@ int vidtv_channel_si_init(struct vidtv_mux *m) goto free_service_list; m->si.eit = vidtv_psi_eit_table_init(m->network_id, - m->transport_stream_id); + m->transport_stream_id, + programs->service_id); if (!m->si.eit) goto free_nit; diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c index 341af312ad56..02dd217bdbf6 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.c +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c @@ -1809,7 +1809,8 @@ void vidtv_psi_eit_event_assign(struct vidtv_psi_table_eit *eit, struct vidtv_psi_table_eit *vidtv_psi_eit_table_init(u16 network_id, - u16 transport_stream_id) + u16 transport_stream_id, + __be16 service_id) { struct vidtv_psi_table_eit *eit; const u16 SYNTAX = 0x1; @@ -1824,7 +1825,7 @@ struct vidtv_psi_table_eit eit->header.bitfield = cpu_to_be16((SYNTAX << 15) | (ONE << 14) | (ONES << 12)); - eit->header.id = cpu_to_be16(network_id); + eit->header.id = service_id; eit->header.current_next = ONE; eit->header.version = 0x1f; diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.h b/drivers/media/test-drivers/vidtv/vidtv_psi.h index 4fcb2c0615bb..d8645d75c3f1 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.h +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.h @@ -738,7 +738,8 @@ struct vidtv_psi_table_eit { struct vidtv_psi_table_eit *vidtv_psi_eit_table_init(u16 network_id, - u16 transport_stream_id); + u16 transport_stream_id, + u16 service_id); /** * struct vidtv_psi_eit_write_args - Arguments for writing an EIT section -- cgit v1.2.3 From 039b7caed173667eccd8725509f3995c661aae82 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 23 Nov 2020 14:16:40 +0100 Subject: 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: Mauro Carvalho Chehab --- drivers/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 77e33f33afee..c3261494120e 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; } @@ -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); 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 d8645d75c3f1..c3bd440e1320 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; -- cgit v1.2.3 From 11f4933f7bc955c16a54bf402383c5d7e4cfa8dc Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 23 Nov 2020 18:04:14 +0100 Subject: media: vidtv: fix service type As the service currently broadcasts just audio, change the service type to reflect that. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_channel.c | 2 +- drivers/media/test-drivers/vidtv/vidtv_psi.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_channel.c b/drivers/media/test-drivers/vidtv/vidtv_channel.c index c3261494120e..4aab3bb67001 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_channel.c +++ b/drivers/media/test-drivers/vidtv/vidtv_channel.c @@ -81,7 +81,7 @@ struct vidtv_channel s302m->service->descriptor = (struct vidtv_psi_desc *) vidtv_psi_service_desc_init(NULL, - DIGITAL_TELEVISION_SERVICE, + DIGITAL_RADIO_SOUND_SERVICE, name, provider); if (!s302m->service->descriptor) diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.h b/drivers/media/test-drivers/vidtv/vidtv_psi.h index c3bd440e1320..4b64715d5759 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.h +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.h @@ -220,6 +220,7 @@ enum service_running_status { enum service_type { /* see ETSI EN 300 468 v1.15.1 p. 77 */ DIGITAL_TELEVISION_SERVICE = 0x1, + DIGITAL_RADIO_SOUND_SERVICE = 0X2, }; /** -- cgit v1.2.3 From bfa4aaebe8c097439feee65f8d39a3bb541b0aea Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 23 Nov 2020 18:40:29 +0100 Subject: media: vidtv: fix service_id at SDT table The service_id there should be equal to the one used on other tables, otherwise, EIT entries won't be valid. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_channel.c | 3 ++- drivers/media/test-drivers/vidtv/vidtv_psi.c | 5 +++-- drivers/media/test-drivers/vidtv/vidtv_psi.h | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_channel.c b/drivers/media/test-drivers/vidtv/vidtv_channel.c index 4aab3bb67001..8ad6c0744d36 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_channel.c +++ b/drivers/media/test-drivers/vidtv/vidtv_channel.c @@ -424,7 +424,8 @@ int vidtv_channel_si_init(struct vidtv_mux *m) if (!m->si.pat) return -ENOMEM; - m->si.sdt = vidtv_psi_sdt_table_init(m->transport_stream_id); + m->si.sdt = vidtv_psi_sdt_table_init(m->network_id, + m->transport_stream_id); if (!m->si.sdt) goto free_pat; diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c index 5c887639b676..77bb560342a6 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.c +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c @@ -1271,7 +1271,8 @@ void vidtv_psi_pmt_table_destroy(struct vidtv_psi_table_pmt *pmt) kfree(pmt); } -struct vidtv_psi_table_sdt *vidtv_psi_sdt_table_init(u16 transport_stream_id) +struct vidtv_psi_table_sdt *vidtv_psi_sdt_table_init(u16 network_id, + u16 transport_stream_id) { struct vidtv_psi_table_sdt *sdt; const u16 RESERVED = 0xff; @@ -1307,7 +1308,7 @@ struct vidtv_psi_table_sdt *vidtv_psi_sdt_table_init(u16 transport_stream_id) * This can be changed to something more useful, when support for * NIT gets added */ - sdt->network_id = cpu_to_be16(0xff01); + sdt->network_id = cpu_to_be16(network_id); sdt->reserved = RESERVED; vidtv_psi_sdt_table_update_sec_len(sdt); diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.h b/drivers/media/test-drivers/vidtv/vidtv_psi.h index 4b64715d5759..d30c8dd53d11 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.h +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.h @@ -366,7 +366,8 @@ struct vidtv_psi_table_pat *vidtv_psi_pat_table_init(u16 transport_stream_id); struct vidtv_psi_table_pmt *vidtv_psi_pmt_table_init(u16 program_number, u16 pcr_pid); -struct vidtv_psi_table_sdt *vidtv_psi_sdt_table_init(u16 transport_stream_id); +struct vidtv_psi_table_sdt *vidtv_psi_sdt_table_init(u16 network_id, + u16 transport_stream_id); struct vidtv_psi_table_sdt_service* vidtv_psi_sdt_service_init(struct vidtv_psi_table_sdt_service *head, -- cgit v1.2.3 From 160028542bb15868c2da0b88bda6335dce221c1c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 23 Nov 2020 16:57:49 +0100 Subject: media: vidtv: add date to the current event The current event is using an undefined date. Instead, it should be the timestamp when the EIT table was generated. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_psi.c | 44 ++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c index 77bb560342a6..fcdd61744ab4 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.c +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c @@ -11,13 +11,16 @@ #define pr_fmt(fmt) KBUILD_MODNAME ":%s, %d: " fmt, __func__, __LINE__ +#include #include #include +#include #include #include #include #include #include +#include #include #include "vidtv_common.h" @@ -1953,16 +1956,51 @@ u32 vidtv_psi_eit_write_into(struct vidtv_psi_eit_write_args args) struct vidtv_psi_table_eit_event *vidtv_psi_eit_event_init(struct vidtv_psi_table_eit_event *head, u16 event_id) { - const u8 DURATION_ONE_HOUR[] = {1, 0, 0}; + const u8 DURATION[] = {0x23, 0x59, 0x59}; /* BCD encoded */ struct vidtv_psi_table_eit_event *e; + struct timespec64 ts; + struct tm time; + int mjd, l; + __be16 mjd_be; e = kzalloc(sizeof(*e), GFP_KERNEL); if (!e) return NULL; e->event_id = cpu_to_be16(event_id); - memset(e->start_time, 0xff, sizeof(e->start_time)); //todo: 0xff means 'unspecified' - memcpy(e->duration, DURATION_ONE_HOUR, sizeof(e->duration)); //todo, default to this for now + + ts = ktime_to_timespec64(ktime_get_real()); + time64_to_tm(ts.tv_sec, 0, &time); + + /* Convert date to Modified Julian Date - per EN 300 468 Annex C */ + if (time.tm_mon < 2) + l = 1; + else + l = 0; + + mjd = 14956 + time.tm_mday; + mjd += (time.tm_year - l) * 36525 / 100; + mjd += (time.tm_mon + 2 + l * 12) * 306001 / 10000; + mjd_be = cpu_to_be16(mjd); + + /* + * Store MJD and hour/min/sec to the event. + * + * Let's make the event to start on a full hour + */ + memcpy(e->start_time, &mjd_be, sizeof(mjd_be)); + e->start_time[2] = bin2bcd(time.tm_hour); + e->start_time[3] = 0; + e->start_time[4] = 0; + + /* + * TODO: for now, the event will last for a day. Should be + * enough for testing purposes, but if one runs the driver + * for more than that, the current event will become invalid. + * So, we need a better code here in order to change the start + * time once the event expires. + */ + memcpy(e->duration, DURATION, sizeof(e->duration)); e->bitfield = cpu_to_be16(RUNNING << 13); -- cgit v1.2.3 From 5edbd330e3a06557642ffb509cc2be39964e26a6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 24 Nov 2020 08:42:20 +0100 Subject: media: vidtv: simplify PSI write function The function vidtv_psi_ts_psi_write_into() initializes the ts_header fields several times, and receives a struct as argument, instead of using a pointer to struct. Cleanup the function, in order to reduce its stack usage and to avoid initializing the ts_header multiple times. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_psi.c | 130 +++++++++++++-------------- 1 file changed, 63 insertions(+), 67 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c index fcdd61744ab4..2b56c642246e 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.c +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c @@ -162,79 +162,75 @@ static void vidtv_psi_set_sec_len(struct vidtv_psi_table_header *h, u16 new_len) * manage the continuity_counter * add stuffing (i.e. padding bytes) after the CRC */ -static u32 vidtv_psi_ts_psi_write_into(struct psi_write_args args) +static u32 vidtv_psi_ts_psi_write_into(struct psi_write_args *args) { - - u32 nbytes_past_boundary = (args.dest_offset % TS_PACKET_LEN); + struct vidtv_mpeg_ts ts_header = { + .sync_byte = TS_SYNC_BYTE, + .bitfield = cpu_to_be16((args->new_psi_section << 14) | args->pid), + .scrambling = 0, + .payload = 1, + .adaptation_field = 0, /* no adaptation field */ + }; + u32 nbytes_past_boundary = (args->dest_offset % TS_PACKET_LEN); bool aligned = (nbytes_past_boundary == 0); - struct vidtv_mpeg_ts ts_header = {}; - u32 remaining_len = args.len; + u32 remaining_len = args->len; u32 payload_write_len = 0; u32 payload_offset = 0; u32 nbytes = 0; - const u16 PAYLOAD_START = args.new_psi_section; - - if (!args.crc && !args.is_crc) + if (!args->crc && !args->is_crc) pr_warn_ratelimited("Missing CRC for chunk\n"); - if (args.crc) - *args.crc = dvb_crc32(*args.crc, args.from, args.len); + if (args->crc) + *args->crc = dvb_crc32(*args->crc, args->from, args->len); - if (args.new_psi_section && !aligned) { + if (args->new_psi_section && !aligned) { pr_warn_ratelimited("Cannot write a new PSI section in a misaligned buffer\n"); /* forcibly align and hope for the best */ - nbytes += vidtv_memset(args.dest_buf, - args.dest_offset + nbytes, - args.dest_buf_sz, + nbytes += vidtv_memset(args->dest_buf, + args->dest_offset + nbytes, + args->dest_buf_sz, TS_FILL_BYTE, TS_PACKET_LEN - nbytes_past_boundary); } while (remaining_len) { - nbytes_past_boundary = (args.dest_offset + nbytes) % TS_PACKET_LEN; + nbytes_past_boundary = (args->dest_offset + nbytes) % TS_PACKET_LEN; aligned = (nbytes_past_boundary == 0); if (aligned) { /* if at a packet boundary, write a new TS header */ - ts_header.sync_byte = TS_SYNC_BYTE; - ts_header.bitfield = cpu_to_be16((PAYLOAD_START << 14) | args.pid); - ts_header.scrambling = 0; - ts_header.continuity_counter = *args.continuity_counter; - ts_header.payload = 1; - /* no adaptation field */ - ts_header.adaptation_field = 0; - - /* copy the header */ - nbytes += vidtv_memcpy(args.dest_buf, - args.dest_offset + nbytes, - args.dest_buf_sz, + ts_header.continuity_counter = *args->continuity_counter; + + nbytes += vidtv_memcpy(args->dest_buf, + args->dest_offset + nbytes, + args->dest_buf_sz, &ts_header, sizeof(ts_header)); /* * This will trigger a discontinuity if the buffer is full, * effectively dropping the packet. */ - vidtv_ts_inc_cc(args.continuity_counter); + vidtv_ts_inc_cc(args->continuity_counter); } /* write the pointer_field in the first byte of the payload */ - if (args.new_psi_section) - nbytes += vidtv_memset(args.dest_buf, - args.dest_offset + nbytes, - args.dest_buf_sz, + if (args->new_psi_section) + nbytes += vidtv_memset(args->dest_buf, + args->dest_offset + nbytes, + args->dest_buf_sz, 0x0, 1); /* write as much of the payload as possible */ - nbytes_past_boundary = (args.dest_offset + nbytes) % TS_PACKET_LEN; + nbytes_past_boundary = (args->dest_offset + nbytes) % TS_PACKET_LEN; payload_write_len = min(TS_PACKET_LEN - nbytes_past_boundary, remaining_len); - nbytes += vidtv_memcpy(args.dest_buf, - args.dest_offset + nbytes, - args.dest_buf_sz, - args.from + payload_offset, + nbytes += vidtv_memcpy(args->dest_buf, + args->dest_offset + nbytes, + args->dest_buf_sz, + args->from + payload_offset, payload_write_len); /* 'payload_write_len' written from a total of 'len' requested*/ @@ -246,12 +242,12 @@ static u32 vidtv_psi_ts_psi_write_into(struct psi_write_args args) * fill the rest of the packet if there is any remaining space unused */ - nbytes_past_boundary = (args.dest_offset + nbytes) % TS_PACKET_LEN; + nbytes_past_boundary = (args->dest_offset + nbytes) % TS_PACKET_LEN; - if (args.is_crc) - nbytes += vidtv_memset(args.dest_buf, - args.dest_offset + nbytes, - args.dest_buf_sz, + if (args->is_crc) + nbytes += vidtv_memset(args->dest_buf, + args->dest_offset + nbytes, + args->dest_buf_sz, TS_FILL_BYTE, TS_PACKET_LEN - nbytes_past_boundary); @@ -275,7 +271,7 @@ static u32 table_section_crc32_write_into(struct crc32_write_args args) psi_args.is_crc = true; psi_args.dest_buf_sz = args.dest_buf_sz; - nbytes += vidtv_psi_ts_psi_write_into(psi_args); + nbytes += vidtv_psi_ts_psi_write_into(&psi_args); return nbytes; } @@ -662,7 +658,7 @@ static u32 vidtv_psi_desc_write_into(struct desc_write_args args) psi_args.dest_buf_sz = args.dest_buf_sz; psi_args.crc = args.crc; - nbytes += vidtv_psi_ts_psi_write_into(psi_args); + nbytes += vidtv_psi_ts_psi_write_into(&psi_args); switch (args.desc->type) { case SERVICE_DESCRIPTOR: @@ -671,25 +667,25 @@ static u32 vidtv_psi_desc_write_into(struct desc_write_args args) sizeof_field(struct vidtv_psi_desc_service, provider_name_len); psi_args.from = &((struct vidtv_psi_desc_service *)args.desc)->service_type; - nbytes += vidtv_psi_ts_psi_write_into(psi_args); + nbytes += vidtv_psi_ts_psi_write_into(&psi_args); psi_args.dest_offset = args.dest_offset + nbytes; psi_args.len = ((struct vidtv_psi_desc_service *)args.desc)->provider_name_len; psi_args.from = ((struct vidtv_psi_desc_service *)args.desc)->provider_name; - nbytes += vidtv_psi_ts_psi_write_into(psi_args); + nbytes += vidtv_psi_ts_psi_write_into(&psi_args); psi_args.dest_offset = args.dest_offset + nbytes; psi_args.len = sizeof_field(struct vidtv_psi_desc_service, service_name_len); psi_args.from = &((struct vidtv_psi_desc_service *)args.desc)->service_name_len; - nbytes += vidtv_psi_ts_psi_write_into(psi_args); + nbytes += vidtv_psi_ts_psi_write_into(&psi_args); psi_args.dest_offset = args.dest_offset + nbytes; psi_args.len = ((struct vidtv_psi_desc_service *)args.desc)->service_name_len; psi_args.from = ((struct vidtv_psi_desc_service *)args.desc)->service_name; - nbytes += vidtv_psi_ts_psi_write_into(psi_args); + nbytes += vidtv_psi_ts_psi_write_into(&psi_args); break; case NETWORK_NAME_DESCRIPTOR: @@ -697,7 +693,7 @@ static u32 vidtv_psi_desc_write_into(struct desc_write_args args) psi_args.len = args.desc->length; psi_args.from = ((struct vidtv_psi_desc_network_name *)args.desc)->network_name; - nbytes += vidtv_psi_ts_psi_write_into(psi_args); + nbytes += vidtv_psi_ts_psi_write_into(&psi_args); break; case SERVICE_LIST_DESCRIPTOR: @@ -708,7 +704,7 @@ static u32 vidtv_psi_desc_write_into(struct desc_write_args args) sizeof(struct vidtv_psi_desc_service_list_entry *); psi_args.from = serv_list_entry; - nbytes += vidtv_psi_ts_psi_write_into(psi_args); + nbytes += vidtv_psi_ts_psi_write_into(&psi_args); serv_list_entry = serv_list_entry->next; } @@ -720,32 +716,32 @@ static u32 vidtv_psi_desc_write_into(struct desc_write_args args) psi_args.from = ((struct vidtv_psi_desc_short_event *) args.desc)->iso_language_code; - nbytes += vidtv_psi_ts_psi_write_into(psi_args); + nbytes += vidtv_psi_ts_psi_write_into(&psi_args); psi_args.dest_offset = args.dest_offset + nbytes; psi_args.len = sizeof_field(struct vidtv_psi_desc_short_event, event_name_len); psi_args.from = &((struct vidtv_psi_desc_short_event *) args.desc)->event_name_len; - nbytes += vidtv_psi_ts_psi_write_into(psi_args); + nbytes += vidtv_psi_ts_psi_write_into(&psi_args); psi_args.dest_offset = args.dest_offset + nbytes; psi_args.len = ((struct vidtv_psi_desc_short_event *)args.desc)->event_name_len; psi_args.from = ((struct vidtv_psi_desc_short_event *)args.desc)->event_name; - nbytes += vidtv_psi_ts_psi_write_into(psi_args); + nbytes += vidtv_psi_ts_psi_write_into(&psi_args); psi_args.dest_offset = args.dest_offset + nbytes; psi_args.len = sizeof_field(struct vidtv_psi_desc_short_event, text_len); psi_args.from = &((struct vidtv_psi_desc_short_event *)args.desc)->text_len; - nbytes += vidtv_psi_ts_psi_write_into(psi_args); + nbytes += vidtv_psi_ts_psi_write_into(&psi_args); psi_args.dest_offset = args.dest_offset + nbytes; psi_args.len = ((struct vidtv_psi_desc_short_event *)args.desc)->text_len; psi_args.from = ((struct vidtv_psi_desc_short_event *)args.desc)->text; - nbytes += vidtv_psi_ts_psi_write_into(psi_args); + nbytes += vidtv_psi_ts_psi_write_into(&psi_args); break; @@ -755,7 +751,7 @@ static u32 vidtv_psi_desc_write_into(struct desc_write_args args) psi_args.len = args.desc->length; psi_args.from = &args.desc->data; - nbytes += vidtv_psi_ts_psi_write_into(psi_args); + nbytes += vidtv_psi_ts_psi_write_into(&psi_args); break; } @@ -780,7 +776,7 @@ vidtv_psi_table_header_write_into(struct header_write_args args) psi_args.dest_buf_sz = args.dest_buf_sz; psi_args.crc = args.crc; - nbytes += vidtv_psi_ts_psi_write_into(psi_args); + nbytes += vidtv_psi_ts_psi_write_into(&psi_args); return nbytes; } @@ -1014,7 +1010,7 @@ u32 vidtv_psi_pat_write_into(struct vidtv_psi_pat_write_args args) sizeof(struct vidtv_psi_table_pat_program *); psi_args.dest_offset = args.offset + nbytes; - nbytes += vidtv_psi_ts_psi_write_into(psi_args); + nbytes += vidtv_psi_ts_psi_write_into(&psi_args); p = p->next; } @@ -1207,7 +1203,7 @@ u32 vidtv_psi_pmt_write_into(struct vidtv_psi_pmt_write_args args) psi_args.dest_buf_sz = args.buf_sz; psi_args.crc = &crc; - nbytes += vidtv_psi_ts_psi_write_into(psi_args); + nbytes += vidtv_psi_ts_psi_write_into(&psi_args); while (table_descriptor) { /* write the descriptors, if any */ @@ -1232,7 +1228,7 @@ u32 vidtv_psi_pmt_write_into(struct vidtv_psi_pmt_write_args args) sizeof_field(struct vidtv_psi_table_pmt_stream, bitfield2); psi_args.dest_offset = args.offset + nbytes; - nbytes += vidtv_psi_ts_psi_write_into(psi_args); + nbytes += vidtv_psi_ts_psi_write_into(&psi_args); stream_descriptor = stream->descriptor; @@ -1360,7 +1356,7 @@ u32 vidtv_psi_sdt_write_into(struct vidtv_psi_sdt_write_args args) psi_args.crc = &crc; /* copy u16 network_id + u8 reserved)*/ - nbytes += vidtv_psi_ts_psi_write_into(psi_args); + nbytes += vidtv_psi_ts_psi_write_into(&psi_args); while (service) { /* copy the services, if any */ @@ -1371,7 +1367,7 @@ u32 vidtv_psi_sdt_write_into(struct vidtv_psi_sdt_write_args args) sizeof(struct vidtv_psi_table_sdt_service *); psi_args.dest_offset = args.offset + nbytes; - nbytes += vidtv_psi_ts_psi_write_into(psi_args); + nbytes += vidtv_psi_ts_psi_write_into(&psi_args); service_desc = service->descriptor; @@ -1694,7 +1690,7 @@ u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args args) psi_args.dest_buf_sz = args.buf_sz; psi_args.crc = &crc; - nbytes += vidtv_psi_ts_psi_write_into(psi_args); + nbytes += vidtv_psi_ts_psi_write_into(&psi_args); while (table_descriptor) { /* write the descriptors, if any */ @@ -1718,7 +1714,7 @@ u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args args) psi_args.dest_offset = args.offset + nbytes; psi_args.pid = VIDTV_NIT_PID; - nbytes += vidtv_psi_ts_psi_write_into(psi_args); + nbytes += vidtv_psi_ts_psi_write_into(&psi_args); while (transport) { /* write the transport sections, if any */ @@ -1728,7 +1724,7 @@ u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args args) sizeof_field(struct vidtv_psi_table_transport, bitfield); psi_args.dest_offset = args.offset + nbytes; - nbytes += vidtv_psi_ts_psi_write_into(psi_args); + nbytes += vidtv_psi_ts_psi_write_into(&psi_args); transport_descriptor = transport->descriptor; @@ -1907,7 +1903,7 @@ u32 vidtv_psi_eit_write_into(struct vidtv_psi_eit_write_args args) psi_args.dest_buf_sz = args.buf_sz; psi_args.crc = &crc; - nbytes += vidtv_psi_ts_psi_write_into(psi_args); + nbytes += vidtv_psi_ts_psi_write_into(&psi_args); while (event) { /* copy the events, if any */ @@ -1918,7 +1914,7 @@ u32 vidtv_psi_eit_write_into(struct vidtv_psi_eit_write_args args) sizeof(struct vidtv_psi_table_eit_event *); psi_args.dest_offset = args.offset + nbytes; - nbytes += vidtv_psi_ts_psi_write_into(psi_args); + nbytes += vidtv_psi_ts_psi_write_into(&psi_args); event_descriptor = event->descriptor; -- cgit v1.2.3 From 9e0067417b26f3d9a6e3292323a160f20620a468 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 24 Nov 2020 08:54:58 +0100 Subject: media: vidtv: simplify the crc writing logic Cleanup the table_section_crc32_write_into() function by initializing struct psi_write_args only once and by passing the args as a pointer. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_psi.c | 39 +++++++++++++--------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c index 2b56c642246e..f02ee4c9a0f7 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.c +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c @@ -254,26 +254,23 @@ static u32 vidtv_psi_ts_psi_write_into(struct psi_write_args *args) return nbytes; } -static u32 table_section_crc32_write_into(struct crc32_write_args args) +static u32 table_section_crc32_write_into(struct crc32_write_args *args) { - struct psi_write_args psi_args = {}; - u32 nbytes = 0; + struct psi_write_args psi_args = { + .dest_buf = args->dest_buf, + .from = &args->crc, + .len = CRC_SIZE_IN_BYTES, + .dest_offset = args->dest_offset, + .pid = args->pid, + .new_psi_section = false, + .continuity_counter = args->continuity_counter, + .is_crc = true, + .dest_buf_sz = args->dest_buf_sz, + }; /* the CRC is the last entry in the section */ - psi_args.dest_buf = args.dest_buf; - psi_args.from = &args.crc; - psi_args.len = CRC_SIZE_IN_BYTES; - psi_args.dest_offset = args.dest_offset; - psi_args.pid = args.pid; - psi_args.new_psi_section = false; - psi_args.continuity_counter = args.continuity_counter; - psi_args.is_crc = true; - psi_args.dest_buf_sz = args.dest_buf_sz; - - nbytes += vidtv_psi_ts_psi_write_into(&psi_args); - - return nbytes; + return vidtv_psi_ts_psi_write_into(&psi_args); } static void vidtv_psi_desc_chain(struct vidtv_psi_desc *head, struct vidtv_psi_desc *desc) @@ -1023,7 +1020,7 @@ u32 vidtv_psi_pat_write_into(struct vidtv_psi_pat_write_args args) c_args.dest_buf_sz = args.buf_sz; /* Write the CRC32 at the end */ - nbytes += table_section_crc32_write_into(c_args); + nbytes += table_section_crc32_write_into(&c_args); return nbytes; } @@ -1258,7 +1255,7 @@ u32 vidtv_psi_pmt_write_into(struct vidtv_psi_pmt_write_args args) c_args.dest_buf_sz = args.buf_sz; /* Write the CRC32 at the end */ - nbytes += table_section_crc32_write_into(c_args); + nbytes += table_section_crc32_write_into(&c_args); return nbytes; } @@ -1397,7 +1394,7 @@ u32 vidtv_psi_sdt_write_into(struct vidtv_psi_sdt_write_args args) c_args.dest_buf_sz = args.buf_sz; /* Write the CRC at the end */ - nbytes += table_section_crc32_write_into(c_args); + nbytes += table_section_crc32_write_into(&c_args); return nbytes; } @@ -1754,7 +1751,7 @@ u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args args) c_args.dest_buf_sz = args.buf_sz; /* Write the CRC32 at the end */ - nbytes += table_section_crc32_write_into(c_args); + nbytes += table_section_crc32_write_into(&c_args); return nbytes; } @@ -1944,7 +1941,7 @@ u32 vidtv_psi_eit_write_into(struct vidtv_psi_eit_write_args args) c_args.dest_buf_sz = args.buf_sz; /* Write the CRC at the end */ - nbytes += table_section_crc32_write_into(c_args); + nbytes += table_section_crc32_write_into(&c_args); return nbytes; } -- cgit v1.2.3 From 974ea17692b59e09c5d0af1a3bc09f45d1892ea4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 24 Nov 2020 09:25:00 +0100 Subject: media: vidtv: cleanup PSI descriptor write function This function initializes the psi_args twice, and receives a struct, instead of a pointer to a struct. Clean it up. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_psi.c | 104 +++++++++++++-------------- 1 file changed, 51 insertions(+), 53 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c index f02ee4c9a0f7..decb9b31c86d 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.c +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c @@ -634,69 +634,67 @@ void vidtv_sdt_desc_assign(struct vidtv_psi_table_sdt *sdt, vidtv_psi_update_version_num(&sdt->header); } -static u32 vidtv_psi_desc_write_into(struct desc_write_args args) +static u32 vidtv_psi_desc_write_into(struct desc_write_args *args) { + struct psi_write_args psi_args = { + .dest_buf = args->dest_buf, + .from = &args->desc->type, + .pid = args->pid, + .new_psi_section = false, + .continuity_counter = args->continuity_counter, + .is_crc = false, + .dest_buf_sz = args->dest_buf_sz, + .crc = args->crc, + .len = sizeof_field(struct vidtv_psi_desc, type) + + sizeof_field(struct vidtv_psi_desc, length), + }; struct vidtv_psi_desc_service_list_entry *serv_list_entry = NULL; - struct psi_write_args psi_args = {}; - /* the number of bytes written by this function */ u32 nbytes = 0; - psi_args.dest_buf = args.dest_buf; - psi_args.from = &args.desc->type; - - psi_args.len = sizeof_field(struct vidtv_psi_desc, type) + - sizeof_field(struct vidtv_psi_desc, length); - - psi_args.dest_offset = args.dest_offset + nbytes; - psi_args.pid = args.pid; - psi_args.new_psi_section = false; - psi_args.continuity_counter = args.continuity_counter; - psi_args.is_crc = false; - psi_args.dest_buf_sz = args.dest_buf_sz; - psi_args.crc = args.crc; + psi_args.dest_offset = args->dest_offset + nbytes; nbytes += vidtv_psi_ts_psi_write_into(&psi_args); - switch (args.desc->type) { + switch (args->desc->type) { case SERVICE_DESCRIPTOR: - psi_args.dest_offset = args.dest_offset + nbytes; + psi_args.dest_offset = args->dest_offset + nbytes; psi_args.len = sizeof_field(struct vidtv_psi_desc_service, service_type) + sizeof_field(struct vidtv_psi_desc_service, provider_name_len); - psi_args.from = &((struct vidtv_psi_desc_service *)args.desc)->service_type; + psi_args.from = &((struct vidtv_psi_desc_service *)args->desc)->service_type; nbytes += vidtv_psi_ts_psi_write_into(&psi_args); - psi_args.dest_offset = args.dest_offset + nbytes; - psi_args.len = ((struct vidtv_psi_desc_service *)args.desc)->provider_name_len; - psi_args.from = ((struct vidtv_psi_desc_service *)args.desc)->provider_name; + psi_args.dest_offset = args->dest_offset + nbytes; + psi_args.len = ((struct vidtv_psi_desc_service *)args->desc)->provider_name_len; + psi_args.from = ((struct vidtv_psi_desc_service *)args->desc)->provider_name; nbytes += vidtv_psi_ts_psi_write_into(&psi_args); - psi_args.dest_offset = args.dest_offset + nbytes; + psi_args.dest_offset = args->dest_offset + nbytes; psi_args.len = sizeof_field(struct vidtv_psi_desc_service, service_name_len); - psi_args.from = &((struct vidtv_psi_desc_service *)args.desc)->service_name_len; + psi_args.from = &((struct vidtv_psi_desc_service *)args->desc)->service_name_len; nbytes += vidtv_psi_ts_psi_write_into(&psi_args); - psi_args.dest_offset = args.dest_offset + nbytes; - psi_args.len = ((struct vidtv_psi_desc_service *)args.desc)->service_name_len; - psi_args.from = ((struct vidtv_psi_desc_service *)args.desc)->service_name; + psi_args.dest_offset = args->dest_offset + nbytes; + psi_args.len = ((struct vidtv_psi_desc_service *)args->desc)->service_name_len; + psi_args.from = ((struct vidtv_psi_desc_service *)args->desc)->service_name; nbytes += vidtv_psi_ts_psi_write_into(&psi_args); break; case NETWORK_NAME_DESCRIPTOR: - psi_args.dest_offset = args.dest_offset + nbytes; - psi_args.len = args.desc->length; - psi_args.from = ((struct vidtv_psi_desc_network_name *)args.desc)->network_name; + psi_args.dest_offset = args->dest_offset + nbytes; + psi_args.len = args->desc->length; + psi_args.from = ((struct vidtv_psi_desc_network_name *)args->desc)->network_name; nbytes += vidtv_psi_ts_psi_write_into(&psi_args); break; case SERVICE_LIST_DESCRIPTOR: - serv_list_entry = ((struct vidtv_psi_desc_service_list *)args.desc)->service_list; + serv_list_entry = ((struct vidtv_psi_desc_service_list *)args->desc)->service_list; while (serv_list_entry) { - psi_args.dest_offset = args.dest_offset + nbytes; + psi_args.dest_offset = args->dest_offset + nbytes; psi_args.len = sizeof(struct vidtv_psi_desc_service_list_entry) - sizeof(struct vidtv_psi_desc_service_list_entry *); psi_args.from = serv_list_entry; @@ -708,35 +706,35 @@ static u32 vidtv_psi_desc_write_into(struct desc_write_args args) break; case SHORT_EVENT_DESCRIPTOR: - psi_args.dest_offset = args.dest_offset + nbytes; + psi_args.dest_offset = args->dest_offset + nbytes; psi_args.len = ISO_LANGUAGE_CODE_LEN; psi_args.from = ((struct vidtv_psi_desc_short_event *) - args.desc)->iso_language_code; + args->desc)->iso_language_code; nbytes += vidtv_psi_ts_psi_write_into(&psi_args); - psi_args.dest_offset = args.dest_offset + nbytes; + psi_args.dest_offset = args->dest_offset + nbytes; psi_args.len = sizeof_field(struct vidtv_psi_desc_short_event, event_name_len); psi_args.from = &((struct vidtv_psi_desc_short_event *) - args.desc)->event_name_len; + args->desc)->event_name_len; nbytes += vidtv_psi_ts_psi_write_into(&psi_args); - psi_args.dest_offset = args.dest_offset + nbytes; - psi_args.len = ((struct vidtv_psi_desc_short_event *)args.desc)->event_name_len; - psi_args.from = ((struct vidtv_psi_desc_short_event *)args.desc)->event_name; + psi_args.dest_offset = args->dest_offset + nbytes; + psi_args.len = ((struct vidtv_psi_desc_short_event *)args->desc)->event_name_len; + psi_args.from = ((struct vidtv_psi_desc_short_event *)args->desc)->event_name; nbytes += vidtv_psi_ts_psi_write_into(&psi_args); - psi_args.dest_offset = args.dest_offset + nbytes; + psi_args.dest_offset = args->dest_offset + nbytes; psi_args.len = sizeof_field(struct vidtv_psi_desc_short_event, text_len); - psi_args.from = &((struct vidtv_psi_desc_short_event *)args.desc)->text_len; + psi_args.from = &((struct vidtv_psi_desc_short_event *)args->desc)->text_len; nbytes += vidtv_psi_ts_psi_write_into(&psi_args); - psi_args.dest_offset = args.dest_offset + nbytes; - psi_args.len = ((struct vidtv_psi_desc_short_event *)args.desc)->text_len; - psi_args.from = ((struct vidtv_psi_desc_short_event *)args.desc)->text; + psi_args.dest_offset = args->dest_offset + nbytes; + psi_args.len = ((struct vidtv_psi_desc_short_event *)args->desc)->text_len; + psi_args.from = ((struct vidtv_psi_desc_short_event *)args->desc)->text; nbytes += vidtv_psi_ts_psi_write_into(&psi_args); @@ -744,9 +742,9 @@ static u32 vidtv_psi_desc_write_into(struct desc_write_args args) case REGISTRATION_DESCRIPTOR: default: - psi_args.dest_offset = args.dest_offset + nbytes; - psi_args.len = args.desc->length; - psi_args.from = &args.desc->data; + psi_args.dest_offset = args->dest_offset + nbytes; + psi_args.len = args->desc->length; + psi_args.from = &args->desc->data; nbytes += vidtv_psi_ts_psi_write_into(&psi_args); break; @@ -1212,7 +1210,7 @@ u32 vidtv_psi_pmt_write_into(struct vidtv_psi_pmt_write_args args) d_args.dest_buf_sz = args.buf_sz; d_args.crc = &crc; - nbytes += vidtv_psi_desc_write_into(d_args); + nbytes += vidtv_psi_desc_write_into(&d_args); table_descriptor = table_descriptor->next; } @@ -1239,7 +1237,7 @@ u32 vidtv_psi_pmt_write_into(struct vidtv_psi_pmt_write_args args) d_args.dest_buf_sz = args.buf_sz; d_args.crc = &crc; - nbytes += vidtv_psi_desc_write_into(d_args); + nbytes += vidtv_psi_desc_write_into(&d_args); stream_descriptor = stream_descriptor->next; } @@ -1378,7 +1376,7 @@ u32 vidtv_psi_sdt_write_into(struct vidtv_psi_sdt_write_args args) d_args.dest_buf_sz = args.buf_sz; d_args.crc = &crc; - nbytes += vidtv_psi_desc_write_into(d_args); + nbytes += vidtv_psi_desc_write_into(&d_args); service_desc = service_desc->next; } @@ -1699,7 +1697,7 @@ u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args args) d_args.dest_buf_sz = args.buf_sz; d_args.crc = &crc; - nbytes += vidtv_psi_desc_write_into(d_args); + nbytes += vidtv_psi_desc_write_into(&d_args); table_descriptor = table_descriptor->next; } @@ -1735,7 +1733,7 @@ u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args args) d_args.dest_buf_sz = args.buf_sz; d_args.crc = &crc; - nbytes += vidtv_psi_desc_write_into(d_args); + nbytes += vidtv_psi_desc_write_into(&d_args); transport_descriptor = transport_descriptor->next; } @@ -1925,7 +1923,7 @@ u32 vidtv_psi_eit_write_into(struct vidtv_psi_eit_write_args args) d_args.dest_buf_sz = args.buf_sz; d_args.crc = &crc; - nbytes += vidtv_psi_desc_write_into(d_args); + nbytes += vidtv_psi_desc_write_into(&d_args); event_descriptor = event_descriptor->next; } -- cgit v1.2.3 From c570fb9ffc056124fe6dc7ea2c69ca3af3093116 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 24 Nov 2020 09:33:44 +0100 Subject: media: vidtv: cleanup PSI table header function - Pass struct header_write_args as a pointer, instead of passing as a var; - Initialize the psi_args struct only once. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_psi.c | 42 +++++++++++++--------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c index decb9b31c86d..c769c7757ef8 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.c +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c @@ -754,26 +754,22 @@ static u32 vidtv_psi_desc_write_into(struct desc_write_args *args) } static u32 -vidtv_psi_table_header_write_into(struct header_write_args args) +vidtv_psi_table_header_write_into(struct header_write_args *args) { - struct psi_write_args psi_args = {}; - /* the number of bytes written by this function */ - u32 nbytes = 0; - - psi_args.dest_buf = args.dest_buf; - psi_args.from = args.h; - psi_args.len = sizeof(struct vidtv_psi_table_header); - psi_args.dest_offset = args.dest_offset; - psi_args.pid = args.pid; - psi_args.new_psi_section = true; - psi_args.continuity_counter = args.continuity_counter; - psi_args.is_crc = false; - psi_args.dest_buf_sz = args.dest_buf_sz; - psi_args.crc = args.crc; - - nbytes += vidtv_psi_ts_psi_write_into(&psi_args); + struct psi_write_args psi_args = { + .dest_buf = args->dest_buf, + .from = args->h, + .len = sizeof(struct vidtv_psi_table_header), + .dest_offset = args->dest_offset, + .pid = args->pid, + .new_psi_section = true, + .continuity_counter = args->continuity_counter, + .is_crc = false, + .dest_buf_sz = args->dest_buf_sz, + .crc = args->crc, + }; - return nbytes; + return vidtv_psi_ts_psi_write_into(&psi_args); } void @@ -985,7 +981,7 @@ u32 vidtv_psi_pat_write_into(struct vidtv_psi_pat_write_args args) h_args.dest_buf_sz = args.buf_sz; h_args.crc = &crc; - nbytes += vidtv_psi_table_header_write_into(h_args); + nbytes += vidtv_psi_table_header_write_into(&h_args); /* note that the field 'u16 programs' is not really part of the PAT */ @@ -1182,7 +1178,7 @@ u32 vidtv_psi_pmt_write_into(struct vidtv_psi_pmt_write_args args) h_args.dest_buf_sz = args.buf_sz; h_args.crc = &crc; - nbytes += vidtv_psi_table_header_write_into(h_args); + nbytes += vidtv_psi_table_header_write_into(&h_args); /* write the two bitfields */ psi_args.dest_buf = args.buf; @@ -1334,7 +1330,7 @@ u32 vidtv_psi_sdt_write_into(struct vidtv_psi_sdt_write_args args) h_args.dest_buf_sz = args.buf_sz; h_args.crc = &crc; - nbytes += vidtv_psi_table_header_write_into(h_args); + nbytes += vidtv_psi_table_header_write_into(&h_args); psi_args.dest_buf = args.buf; psi_args.from = &args.sdt->network_id; @@ -1670,7 +1666,7 @@ u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args args) h_args.dest_buf_sz = args.buf_sz; h_args.crc = &crc; - nbytes += vidtv_psi_table_header_write_into(h_args); + nbytes += vidtv_psi_table_header_write_into(&h_args); /* write the bitfield */ psi_args.dest_buf = args.buf; @@ -1880,7 +1876,7 @@ u32 vidtv_psi_eit_write_into(struct vidtv_psi_eit_write_args args) h_args.dest_buf_sz = args.buf_sz; h_args.crc = &crc; - nbytes += vidtv_psi_table_header_write_into(h_args); + nbytes += vidtv_psi_table_header_write_into(&h_args); psi_args.dest_buf = args.buf; psi_args.from = &args.eit->transport_id; -- cgit v1.2.3 From 7f957515191af5ad78f9905afad5fae584988986 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 24 Nov 2020 09:45:49 +0100 Subject: media: vidtv: cleanup PAT write function Avoid initializing the structs multiple times and pass the PAT struct as a pointer, instead of a var. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_mux.c | 2 +- drivers/media/test-drivers/vidtv/vidtv_psi.c | 57 +++++++++++++++------------- drivers/media/test-drivers/vidtv/vidtv_psi.h | 2 +- 3 files changed, 32 insertions(+), 29 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_mux.c b/drivers/media/test-drivers/vidtv/vidtv_mux.c index 0cf784c09024..200a8000603f 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_mux.c +++ b/drivers/media/test-drivers/vidtv/vidtv_mux.c @@ -173,7 +173,7 @@ static u32 vidtv_mux_push_si(struct vidtv_mux *m) pat_args.offset = m->mux_buf_offset; pat_args.continuity_counter = &pat_ctx->cc; - 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->num_pmt; ++i) { pmt_pid = vidtv_psi_pmt_get_pid(m->si.pmt_secs[i], diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c index c769c7757ef8..722be777ff01 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.c +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c @@ -961,57 +961,60 @@ struct vidtv_psi_table_pat *vidtv_psi_pat_table_init(u16 transport_stream_id) return pat; } -u32 vidtv_psi_pat_write_into(struct vidtv_psi_pat_write_args args) +u32 vidtv_psi_pat_write_into(struct vidtv_psi_pat_write_args *args) { - struct vidtv_psi_table_pat_program *p = args.pat->program; - struct header_write_args h_args = {}; - struct psi_write_args psi_args = {}; - struct crc32_write_args c_args = {}; - const u16 pat_pid = VIDTV_PAT_PID; + struct vidtv_psi_table_pat_program *p = args->pat->program; + struct header_write_args h_args = { + .dest_buf = args->buf, + .dest_offset = args->offset, + .pid = VIDTV_PAT_PID, + .h = &args->pat->header, + .continuity_counter = args->continuity_counter, + .dest_buf_sz = args->buf_sz, + }; + struct psi_write_args psi_args = { + .dest_buf = args->buf, + .pid = VIDTV_PAT_PID, + .new_psi_section = false, + .continuity_counter = args->continuity_counter, + .is_crc = false, + .dest_buf_sz = args->buf_sz, + }; + struct crc32_write_args c_args = { + .dest_buf = args->buf, + .pid = VIDTV_PAT_PID, + .dest_buf_sz = args->buf_sz, + }; u32 crc = INITIAL_CRC; u32 nbytes = 0; - vidtv_psi_pat_table_update_sec_len(args.pat); + vidtv_psi_pat_table_update_sec_len(args->pat); - h_args.dest_buf = args.buf; - h_args.dest_offset = args.offset; - h_args.h = &args.pat->header; - h_args.pid = pat_pid; - h_args.continuity_counter = args.continuity_counter; - h_args.dest_buf_sz = args.buf_sz; h_args.crc = &crc; nbytes += vidtv_psi_table_header_write_into(&h_args); /* note that the field 'u16 programs' is not really part of the PAT */ - psi_args.dest_buf = args.buf; - psi_args.pid = pat_pid; - psi_args.new_psi_section = false; - psi_args.continuity_counter = args.continuity_counter; - psi_args.is_crc = false; - psi_args.dest_buf_sz = args.buf_sz; - psi_args.crc = &crc; + psi_args.crc = &crc; while (p) { /* copy the PAT programs */ psi_args.from = p; /* skip the pointer */ psi_args.len = sizeof(*p) - - sizeof(struct vidtv_psi_table_pat_program *); - psi_args.dest_offset = args.offset + nbytes; + sizeof(struct vidtv_psi_table_pat_program *); + psi_args.dest_offset = args->offset + nbytes; + psi_args.continuity_counter = args->continuity_counter; nbytes += vidtv_psi_ts_psi_write_into(&psi_args); p = p->next; } - c_args.dest_buf = args.buf; - c_args.dest_offset = args.offset + nbytes; + c_args.dest_offset = args->offset + nbytes; + c_args.continuity_counter = args->continuity_counter; c_args.crc = cpu_to_be32(crc); - c_args.pid = pat_pid; - c_args.continuity_counter = args.continuity_counter; - c_args.dest_buf_sz = args.buf_sz; /* Write the CRC32 at the end */ nbytes += table_section_crc32_write_into(&c_args); diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.h b/drivers/media/test-drivers/vidtv/vidtv_psi.h index d30c8dd53d11..b6c0518ef4a4 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.h +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.h @@ -556,7 +556,7 @@ struct vidtv_psi_pat_write_args { * equal to the size of the PAT, since more space is needed for TS headers during TS * encapsulation. */ -u32 vidtv_psi_pat_write_into(struct vidtv_psi_pat_write_args args); +u32 vidtv_psi_pat_write_into(struct vidtv_psi_pat_write_args *args); /** * struct vidtv_psi_sdt_write_args - Arguments for writing a SDT table -- cgit v1.2.3 From db9569f67e2ea14f896d1a6303906294bef900ad Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 24 Nov 2020 09:58:31 +0100 Subject: media: vidtv: cleanup PMT write table function - Pass struct vidtv_psi_pmt_write_args as a pointer; - Avoid initializing structs multiple times. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_mux.c | 2 +- drivers/media/test-drivers/vidtv/vidtv_psi.c | 91 ++++++++++++++-------------- drivers/media/test-drivers/vidtv/vidtv_psi.h | 2 +- 3 files changed, 46 insertions(+), 49 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_mux.c b/drivers/media/test-drivers/vidtv/vidtv_mux.c index 200a8000603f..239e0a242b6e 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_mux.c +++ b/drivers/media/test-drivers/vidtv/vidtv_mux.c @@ -193,7 +193,7 @@ static u32 vidtv_mux_push_si(struct vidtv_mux *m) pmt_args.continuity_counter = &pmt_ctx->cc; /* write each section into buffer */ - m->mux_buf_offset += vidtv_psi_pmt_write_into(pmt_args); + m->mux_buf_offset += vidtv_psi_pmt_write_into(&pmt_args); } sdt_args.offset = m->mux_buf_offset; diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c index 722be777ff01..677cf7fac731 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.c +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c @@ -1159,54 +1159,58 @@ struct vidtv_psi_table_pmt *vidtv_psi_pmt_table_init(u16 program_number, return pmt; } -u32 vidtv_psi_pmt_write_into(struct vidtv_psi_pmt_write_args args) +u32 vidtv_psi_pmt_write_into(struct vidtv_psi_pmt_write_args *args) { - struct vidtv_psi_desc *table_descriptor = args.pmt->descriptor; - struct vidtv_psi_table_pmt_stream *stream = args.pmt->stream; + struct vidtv_psi_desc *table_descriptor = args->pmt->descriptor; + struct vidtv_psi_table_pmt_stream *stream = args->pmt->stream; struct vidtv_psi_desc *stream_descriptor; - struct header_write_args h_args = {}; - struct psi_write_args psi_args = {}; - struct desc_write_args d_args = {}; - struct crc32_write_args c_args = {}; + struct header_write_args h_args = { + .dest_buf = args->buf, + .dest_offset = args->offset, + .h = &args->pmt->header, + .pid = args->pid, + .continuity_counter = args->continuity_counter, + .dest_buf_sz = args->buf_sz, + }; + struct psi_write_args psi_args = { + .dest_buf = args->buf, + .from = &args->pmt->bitfield, + .len = sizeof_field(struct vidtv_psi_table_pmt, bitfield) + + sizeof_field(struct vidtv_psi_table_pmt, bitfield2), + .pid = args->pid, + .new_psi_section = false, + .is_crc = false, + .dest_buf_sz = args->buf_sz, + }; + struct desc_write_args d_args = { + .dest_buf = args->buf, + .desc = table_descriptor, + .pid = args->pid, + .dest_buf_sz = args->buf_sz, + }; + struct crc32_write_args c_args = { + .dest_buf = args->buf, + .pid = args->pid, + .dest_buf_sz = args->buf_sz, + }; u32 crc = INITIAL_CRC; u32 nbytes = 0; - vidtv_psi_pmt_table_update_sec_len(args.pmt); + vidtv_psi_pmt_table_update_sec_len(args->pmt); - h_args.dest_buf = args.buf; - h_args.dest_offset = args.offset; - h_args.h = &args.pmt->header; - h_args.pid = args.pid; - h_args.continuity_counter = args.continuity_counter; - h_args.dest_buf_sz = args.buf_sz; h_args.crc = &crc; nbytes += vidtv_psi_table_header_write_into(&h_args); /* write the two bitfields */ - psi_args.dest_buf = args.buf; - psi_args.from = &args.pmt->bitfield; - psi_args.len = sizeof_field(struct vidtv_psi_table_pmt, bitfield) + - sizeof_field(struct vidtv_psi_table_pmt, bitfield2); - - psi_args.dest_offset = args.offset + nbytes; - psi_args.pid = args.pid; - psi_args.new_psi_section = false; - psi_args.continuity_counter = args.continuity_counter; - psi_args.is_crc = false; - psi_args.dest_buf_sz = args.buf_sz; - psi_args.crc = &crc; - + psi_args.dest_offset = args->offset + nbytes; + psi_args.continuity_counter = args->continuity_counter; nbytes += vidtv_psi_ts_psi_write_into(&psi_args); while (table_descriptor) { /* write the descriptors, if any */ - d_args.dest_buf = args.buf; - d_args.dest_offset = args.offset + nbytes; - d_args.desc = table_descriptor; - d_args.pid = args.pid; - d_args.continuity_counter = args.continuity_counter; - d_args.dest_buf_sz = args.buf_sz; + d_args.dest_offset = args->offset + nbytes; + d_args.continuity_counter = args->continuity_counter; d_args.crc = &crc; nbytes += vidtv_psi_desc_write_into(&d_args); @@ -1214,13 +1218,12 @@ u32 vidtv_psi_pmt_write_into(struct vidtv_psi_pmt_write_args args) table_descriptor = table_descriptor->next; } + psi_args.len += sizeof_field(struct vidtv_psi_table_pmt_stream, type); while (stream) { /* write the streams, if any */ psi_args.from = stream; - psi_args.len = sizeof_field(struct vidtv_psi_table_pmt_stream, type) + - sizeof_field(struct vidtv_psi_table_pmt_stream, bitfield) + - sizeof_field(struct vidtv_psi_table_pmt_stream, bitfield2); - psi_args.dest_offset = args.offset + nbytes; + psi_args.dest_offset = args->offset + nbytes; + psi_args.continuity_counter = args->continuity_counter; nbytes += vidtv_psi_ts_psi_write_into(&psi_args); @@ -1228,12 +1231,9 @@ u32 vidtv_psi_pmt_write_into(struct vidtv_psi_pmt_write_args args) while (stream_descriptor) { /* write the stream descriptors, if any */ - d_args.dest_buf = args.buf; - d_args.dest_offset = args.offset + nbytes; + d_args.dest_offset = args->offset + nbytes; d_args.desc = stream_descriptor; - d_args.pid = args.pid; - d_args.continuity_counter = args.continuity_counter; - d_args.dest_buf_sz = args.buf_sz; + d_args.continuity_counter = args->continuity_counter; d_args.crc = &crc; nbytes += vidtv_psi_desc_write_into(&d_args); @@ -1244,12 +1244,9 @@ u32 vidtv_psi_pmt_write_into(struct vidtv_psi_pmt_write_args args) stream = stream->next; } - c_args.dest_buf = args.buf; - c_args.dest_offset = args.offset + nbytes; + c_args.dest_offset = args->offset + nbytes; c_args.crc = cpu_to_be32(crc); - c_args.pid = args.pid; - c_args.continuity_counter = args.continuity_counter; - c_args.dest_buf_sz = args.buf_sz; + c_args.continuity_counter = args->continuity_counter; /* Write the CRC32 at the end */ nbytes += table_section_crc32_write_into(&c_args); diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.h b/drivers/media/test-drivers/vidtv/vidtv_psi.h index b6c0518ef4a4..e1a30455ebbb 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.h +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.h @@ -621,7 +621,7 @@ struct vidtv_psi_pmt_write_args { * equal to the size of the PMT section, since more space is needed for TS headers * during TS encapsulation. */ -u32 vidtv_psi_pmt_write_into(struct vidtv_psi_pmt_write_args args); +u32 vidtv_psi_pmt_write_into(struct vidtv_psi_pmt_write_args *args); /** * vidtv_psi_find_pmt_sec - Finds the PMT section for 'program_num' -- cgit v1.2.3 From 6286a4b79b6cc5b4696145a1c3216d0c264efcf7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 24 Nov 2020 10:20:23 +0100 Subject: media: vidtv: simplify SDT write function - pass struct vidtv_psi_sdt_write_args as a pointer; - avoid initializing struct fields multiple times. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_mux.c | 2 +- drivers/media/test-drivers/vidtv/vidtv_psi.c | 85 ++++++++++++++-------------- drivers/media/test-drivers/vidtv/vidtv_psi.h | 2 +- 3 files changed, 46 insertions(+), 43 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_mux.c b/drivers/media/test-drivers/vidtv/vidtv_mux.c index 239e0a242b6e..ff1c7c586838 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_mux.c +++ b/drivers/media/test-drivers/vidtv/vidtv_mux.c @@ -199,7 +199,7 @@ static u32 vidtv_mux_push_si(struct vidtv_mux *m) sdt_args.offset = m->mux_buf_offset; sdt_args.continuity_counter = &sdt_ctx->cc; - m->mux_buf_offset += vidtv_psi_sdt_write_into(sdt_args); + m->mux_buf_offset += vidtv_psi_sdt_write_into(&sdt_args); nit_args.offset = m->mux_buf_offset; nit_args.continuity_counter = &nit_ctx->cc; diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c index 677cf7fac731..f8cfcd7f42d3 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.c +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c @@ -1306,57 +1306,66 @@ struct vidtv_psi_table_sdt *vidtv_psi_sdt_table_init(u16 network_id, return sdt; } -u32 vidtv_psi_sdt_write_into(struct vidtv_psi_sdt_write_args args) +u32 vidtv_psi_sdt_write_into(struct vidtv_psi_sdt_write_args *args) { - struct vidtv_psi_table_sdt_service *service = args.sdt->service; + struct header_write_args h_args = { + .dest_buf = args->buf, + .dest_offset = args->offset, + .h = &args->sdt->header, + .pid = VIDTV_SDT_PID, + .dest_buf_sz = args->buf_sz, + }; + struct psi_write_args psi_args = { + .dest_buf = args->buf, + .len = sizeof_field(struct vidtv_psi_table_sdt, network_id) + + sizeof_field(struct vidtv_psi_table_sdt, reserved), + .pid = VIDTV_SDT_PID, + .new_psi_section = false, + .is_crc = false, + .dest_buf_sz = args->buf_sz, + }; + struct desc_write_args d_args = { + .dest_buf = args->buf, + .pid = VIDTV_SDT_PID, + .dest_buf_sz = args->buf_sz, + }; + struct crc32_write_args c_args = { + .dest_buf = args->buf, + .pid = VIDTV_SDT_PID, + .dest_buf_sz = args->buf_sz, + }; + struct vidtv_psi_table_sdt_service *service = args->sdt->service; struct vidtv_psi_desc *service_desc; - struct header_write_args h_args = {}; - struct psi_write_args psi_args = {}; - struct desc_write_args d_args = {}; - struct crc32_write_args c_args = {}; - u16 sdt_pid = VIDTV_SDT_PID; u32 nbytes = 0; u32 crc = INITIAL_CRC; /* see ETSI EN 300 468 v1.15.1 p. 11 */ - vidtv_psi_sdt_table_update_sec_len(args.sdt); + vidtv_psi_sdt_table_update_sec_len(args->sdt); - h_args.dest_buf = args.buf; - h_args.dest_offset = args.offset; - h_args.h = &args.sdt->header; - h_args.pid = sdt_pid; - h_args.continuity_counter = args.continuity_counter; - h_args.dest_buf_sz = args.buf_sz; + h_args.continuity_counter = args->continuity_counter; h_args.crc = &crc; nbytes += vidtv_psi_table_header_write_into(&h_args); - psi_args.dest_buf = args.buf; - psi_args.from = &args.sdt->network_id; - - psi_args.len = sizeof_field(struct vidtv_psi_table_sdt, network_id) + - sizeof_field(struct vidtv_psi_table_sdt, reserved); - - psi_args.dest_offset = args.offset + nbytes; - psi_args.pid = sdt_pid; - psi_args.new_psi_section = false; - psi_args.continuity_counter = args.continuity_counter; - psi_args.is_crc = false; - psi_args.dest_buf_sz = args.buf_sz; + psi_args.from = &args->sdt->network_id; + psi_args.dest_offset = args->offset + nbytes; + psi_args.continuity_counter = args->continuity_counter; psi_args.crc = &crc; /* copy u16 network_id + u8 reserved)*/ nbytes += vidtv_psi_ts_psi_write_into(&psi_args); + /* skip both pointers at the end */ + psi_args.len = sizeof(struct vidtv_psi_table_sdt_service) - + sizeof(struct vidtv_psi_desc *) - + sizeof(struct vidtv_psi_table_sdt_service *); + while (service) { /* copy the services, if any */ psi_args.from = service; - /* skip both pointers at the end */ - psi_args.len = sizeof(struct vidtv_psi_table_sdt_service) - - sizeof(struct vidtv_psi_desc *) - - sizeof(struct vidtv_psi_table_sdt_service *); - psi_args.dest_offset = args.offset + nbytes; + psi_args.dest_offset = args->offset + nbytes; + psi_args.continuity_counter = args->continuity_counter; nbytes += vidtv_psi_ts_psi_write_into(&psi_args); @@ -1364,12 +1373,9 @@ u32 vidtv_psi_sdt_write_into(struct vidtv_psi_sdt_write_args args) while (service_desc) { /* copy the service descriptors, if any */ - d_args.dest_buf = args.buf; - d_args.dest_offset = args.offset + nbytes; + d_args.dest_offset = args->offset + nbytes; d_args.desc = service_desc; - d_args.pid = sdt_pid; - d_args.continuity_counter = args.continuity_counter; - d_args.dest_buf_sz = args.buf_sz; + d_args.continuity_counter = args->continuity_counter; d_args.crc = &crc; nbytes += vidtv_psi_desc_write_into(&d_args); @@ -1380,12 +1386,9 @@ u32 vidtv_psi_sdt_write_into(struct vidtv_psi_sdt_write_args args) service = service->next; } - c_args.dest_buf = args.buf; - c_args.dest_offset = args.offset + nbytes; + c_args.dest_offset = args->offset + nbytes; c_args.crc = cpu_to_be32(crc); - c_args.pid = sdt_pid; - c_args.continuity_counter = args.continuity_counter; - c_args.dest_buf_sz = args.buf_sz; + c_args.continuity_counter = args->continuity_counter; /* Write the CRC at the end */ nbytes += table_section_crc32_write_into(&c_args); diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.h b/drivers/media/test-drivers/vidtv/vidtv_psi.h index e1a30455ebbb..e3913fbe7832 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.h +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.h @@ -588,7 +588,7 @@ struct vidtv_psi_sdt_write_args { * equal to the size of the SDT, since more space is needed for TS headers during TS * encapsulation. */ -u32 vidtv_psi_sdt_write_into(struct vidtv_psi_sdt_write_args args); +u32 vidtv_psi_sdt_write_into(struct vidtv_psi_sdt_write_args *args); /** * struct vidtv_psi_pmt_write_args - Arguments for writing a PMT section -- cgit v1.2.3 From 5a5b9fb1a1117b2cf71a162309e370850a626dbf Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 24 Nov 2020 10:37:12 +0100 Subject: media: vidtv: simplify NIT write function - pass struct vidtv_psi_nit_write_args as a pointer; - avoid initializing struct fields multiple times. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_mux.c | 2 +- drivers/media/test-drivers/vidtv/vidtv_psi.c | 91 ++++++++++++++-------------- drivers/media/test-drivers/vidtv/vidtv_psi.h | 2 +- 3 files changed, 47 insertions(+), 48 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_mux.c b/drivers/media/test-drivers/vidtv/vidtv_mux.c index ff1c7c586838..77d691f4ff92 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_mux.c +++ b/drivers/media/test-drivers/vidtv/vidtv_mux.c @@ -204,7 +204,7 @@ static u32 vidtv_mux_push_si(struct vidtv_mux *m) nit_args.offset = m->mux_buf_offset; nit_args.continuity_counter = &nit_ctx->cc; - m->mux_buf_offset += vidtv_psi_nit_write_into(nit_args); + m->mux_buf_offset += vidtv_psi_nit_write_into(&nit_args); eit_args.offset = m->mux_buf_offset; eit_args.continuity_counter = &eit_ctx->cc; diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c index f8cfcd7f42d3..b03e235b0a67 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.c +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c @@ -1647,53 +1647,60 @@ free_nit: return NULL; } -u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args args) +u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args *args) { - struct vidtv_psi_desc *table_descriptor = args.nit->descriptor; - struct vidtv_psi_table_transport *transport = args.nit->transport; + struct header_write_args h_args = { + .dest_buf = args->buf, + .dest_offset = args->offset, + .h = &args->nit->header, + .pid = VIDTV_NIT_PID, + .dest_buf_sz = args->buf_sz, + }; + struct psi_write_args psi_args = { + .dest_buf = args->buf, + .from = &args->nit->bitfield, + .len = sizeof_field(struct vidtv_psi_table_nit, bitfield), + .pid = VIDTV_NIT_PID, + .new_psi_section = false, + .is_crc = false, + .dest_buf_sz = args->buf_sz, + }; + struct desc_write_args d_args = { + .dest_buf = args->buf, + .pid = VIDTV_NIT_PID, + .dest_buf_sz = args->buf_sz, + }; + struct crc32_write_args c_args = { + .dest_buf = args->buf, + .pid = VIDTV_NIT_PID, + .dest_buf_sz = args->buf_sz, + }; + struct vidtv_psi_desc *table_descriptor = args->nit->descriptor; + struct vidtv_psi_table_transport *transport = args->nit->transport; struct vidtv_psi_desc *transport_descriptor; - struct header_write_args h_args = {}; - struct psi_write_args psi_args = {}; - struct desc_write_args d_args = {}; - struct crc32_write_args c_args = {}; u32 crc = INITIAL_CRC; u32 nbytes = 0; - vidtv_psi_nit_table_update_sec_len(args.nit); + vidtv_psi_nit_table_update_sec_len(args->nit); - h_args.dest_buf = args.buf; - h_args.dest_offset = args.offset; - h_args.h = &args.nit->header; - h_args.pid = VIDTV_NIT_PID; - h_args.continuity_counter = args.continuity_counter; - h_args.dest_buf_sz = args.buf_sz; + h_args.continuity_counter = args->continuity_counter; h_args.crc = &crc; nbytes += vidtv_psi_table_header_write_into(&h_args); /* write the bitfield */ - psi_args.dest_buf = args.buf; - psi_args.from = &args.nit->bitfield; - psi_args.len = sizeof_field(struct vidtv_psi_table_nit, bitfield); - psi_args.dest_offset = args.offset + nbytes; - psi_args.pid = VIDTV_NIT_PID; - psi_args.new_psi_section = false; - psi_args.continuity_counter = args.continuity_counter; - psi_args.is_crc = false; - psi_args.dest_buf_sz = args.buf_sz; + psi_args.dest_offset = args->offset + nbytes; + psi_args.continuity_counter = args->continuity_counter; psi_args.crc = &crc; nbytes += vidtv_psi_ts_psi_write_into(&psi_args); while (table_descriptor) { /* write the descriptors, if any */ - d_args.dest_buf = args.buf; - d_args.dest_offset = args.offset + nbytes; + d_args.dest_offset = args->offset + nbytes; d_args.desc = table_descriptor; - d_args.pid = VIDTV_NIT_PID; - d_args.continuity_counter = args.continuity_counter; - d_args.dest_buf_sz = args.buf_sz; + d_args.continuity_counter = args->continuity_counter; d_args.crc = &crc; nbytes += vidtv_psi_desc_write_into(&d_args); @@ -1702,21 +1709,19 @@ u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args args) } /* write the second bitfield */ - psi_args.dest_buf = args.buf; - psi_args.from = &args.nit->bitfield2; + psi_args.from = &args->nit->bitfield2; psi_args.len = sizeof_field(struct vidtv_psi_table_nit, bitfield2); - psi_args.dest_offset = args.offset + nbytes; - psi_args.pid = VIDTV_NIT_PID; + psi_args.dest_offset = args->offset + nbytes; nbytes += vidtv_psi_ts_psi_write_into(&psi_args); + psi_args.len = sizeof_field(struct vidtv_psi_table_transport, transport_id) + + sizeof_field(struct vidtv_psi_table_transport, network_id) + + sizeof_field(struct vidtv_psi_table_transport, bitfield); while (transport) { /* write the transport sections, if any */ psi_args.from = transport; - psi_args.len = sizeof_field(struct vidtv_psi_table_transport, transport_id) + - sizeof_field(struct vidtv_psi_table_transport, network_id) + - sizeof_field(struct vidtv_psi_table_transport, bitfield); - psi_args.dest_offset = args.offset + nbytes; + psi_args.dest_offset = args->offset + nbytes; nbytes += vidtv_psi_ts_psi_write_into(&psi_args); @@ -1724,12 +1729,9 @@ u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args args) while (transport_descriptor) { /* write the transport descriptors, if any */ - d_args.dest_buf = args.buf; - d_args.dest_offset = args.offset + nbytes; + d_args.dest_offset = args->offset + nbytes; d_args.desc = transport_descriptor; - d_args.pid = VIDTV_NIT_PID; - d_args.continuity_counter = args.continuity_counter; - d_args.dest_buf_sz = args.buf_sz; + d_args.continuity_counter = args->continuity_counter; d_args.crc = &crc; nbytes += vidtv_psi_desc_write_into(&d_args); @@ -1740,12 +1742,9 @@ u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args args) transport = transport->next; } - c_args.dest_buf = args.buf; - c_args.dest_offset = args.offset + nbytes; + c_args.dest_offset = args->offset + nbytes; c_args.crc = cpu_to_be32(crc); - c_args.pid = VIDTV_NIT_PID; - c_args.continuity_counter = args.continuity_counter; - c_args.dest_buf_sz = args.buf_sz; + c_args.continuity_counter = args->continuity_counter; /* Write the CRC32 at the end */ nbytes += table_section_crc32_write_into(&c_args); diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.h b/drivers/media/test-drivers/vidtv/vidtv_psi.h index e3913fbe7832..8e366ea44cca 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.h +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.h @@ -709,7 +709,7 @@ struct vidtv_psi_nit_write_args { * equal to the size of the NIT, since more space is needed for TS headers during TS * encapsulation. */ -u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args args); +u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args *args); void vidtv_psi_nit_table_destroy(struct vidtv_psi_table_nit *nit); -- cgit v1.2.3 From b087982886e24dd9b50457d4263910ae671be177 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 24 Nov 2020 10:50:58 +0100 Subject: media: vidtv: simplify EIT write function - pass struct vidtv_psi_eit_write_args as a pointer; - avoid initializing struct fields multiple times. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vidtv/vidtv_mux.c | 2 +- drivers/media/test-drivers/vidtv/vidtv_psi.c | 86 ++++++++++++++-------------- drivers/media/test-drivers/vidtv/vidtv_psi.h | 2 +- 3 files changed, 46 insertions(+), 44 deletions(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_mux.c b/drivers/media/test-drivers/vidtv/vidtv_mux.c index 77d691f4ff92..b51e6a3b8cbe 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_mux.c +++ b/drivers/media/test-drivers/vidtv/vidtv_mux.c @@ -209,7 +209,7 @@ static u32 vidtv_mux_push_si(struct vidtv_mux *m) eit_args.offset = m->mux_buf_offset; eit_args.continuity_counter = &eit_ctx->cc; - m->mux_buf_offset += vidtv_psi_eit_write_into(eit_args); + m->mux_buf_offset += vidtv_psi_eit_write_into(&eit_args); nbytes = m->mux_buf_offset - initial_offset; diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c index b03e235b0a67..4511a2a98405 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.c +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c @@ -1857,55 +1857,63 @@ struct vidtv_psi_table_eit return eit; } -u32 vidtv_psi_eit_write_into(struct vidtv_psi_eit_write_args args) +u32 vidtv_psi_eit_write_into(struct vidtv_psi_eit_write_args *args) { - struct vidtv_psi_table_eit_event *event = args.eit->event; + struct header_write_args h_args = { + .dest_buf = args->buf, + .dest_offset = args->offset, + .h = &args->eit->header, + .pid = VIDTV_EIT_PID, + .dest_buf_sz = args->buf_sz, + }; + struct psi_write_args psi_args = { + .dest_buf = args->buf, + .len = sizeof_field(struct vidtv_psi_table_eit, transport_id) + + sizeof_field(struct vidtv_psi_table_eit, network_id) + + sizeof_field(struct vidtv_psi_table_eit, last_segment) + + sizeof_field(struct vidtv_psi_table_eit, last_table_id), + .pid = VIDTV_EIT_PID, + .new_psi_section = false, + .is_crc = false, + .dest_buf_sz = args->buf_sz, + }; + struct desc_write_args d_args = { + .dest_buf = args->buf, + .pid = VIDTV_EIT_PID, + .dest_buf_sz = args->buf_sz, + }; + struct crc32_write_args c_args = { + .dest_buf = args->buf, + .pid = VIDTV_EIT_PID, + .dest_buf_sz = args->buf_sz, + }; + struct vidtv_psi_table_eit_event *event = args->eit->event; struct vidtv_psi_desc *event_descriptor; - struct header_write_args h_args = {}; - struct psi_write_args psi_args = {}; - struct desc_write_args d_args = {}; - struct crc32_write_args c_args = {}; u32 crc = INITIAL_CRC; u32 nbytes = 0; - vidtv_psi_eit_table_update_sec_len(args.eit); + vidtv_psi_eit_table_update_sec_len(args->eit); - h_args.dest_buf = args.buf; - h_args.dest_offset = args.offset; - h_args.h = &args.eit->header; - h_args.pid = VIDTV_EIT_PID; - h_args.continuity_counter = args.continuity_counter; - h_args.dest_buf_sz = args.buf_sz; + h_args.continuity_counter = args->continuity_counter; h_args.crc = &crc; nbytes += vidtv_psi_table_header_write_into(&h_args); - psi_args.dest_buf = args.buf; - psi_args.from = &args.eit->transport_id; - - psi_args.len = sizeof_field(struct vidtv_psi_table_eit, transport_id) + - sizeof_field(struct vidtv_psi_table_eit, network_id) + - sizeof_field(struct vidtv_psi_table_eit, last_segment) + - sizeof_field(struct vidtv_psi_table_eit, last_table_id); - - psi_args.dest_offset = args.offset + nbytes; - psi_args.pid = VIDTV_EIT_PID; - psi_args.new_psi_section = false; - psi_args.continuity_counter = args.continuity_counter; - psi_args.is_crc = false; - psi_args.dest_buf_sz = args.buf_sz; + psi_args.from = &args->eit->transport_id; + psi_args.dest_offset = args->offset + nbytes; + psi_args.continuity_counter = args->continuity_counter; psi_args.crc = &crc; nbytes += vidtv_psi_ts_psi_write_into(&psi_args); + /* skip both pointers at the end */ + psi_args.len = sizeof(struct vidtv_psi_table_eit_event) - + sizeof(struct vidtv_psi_desc *) - + sizeof(struct vidtv_psi_table_eit_event *); while (event) { /* copy the events, if any */ psi_args.from = event; - /* skip both pointers at the end */ - psi_args.len = sizeof(struct vidtv_psi_table_eit_event) - - sizeof(struct vidtv_psi_desc *) - - sizeof(struct vidtv_psi_table_eit_event *); - psi_args.dest_offset = args.offset + nbytes; + psi_args.dest_offset = args->offset + nbytes; nbytes += vidtv_psi_ts_psi_write_into(&psi_args); @@ -1913,12 +1921,9 @@ u32 vidtv_psi_eit_write_into(struct vidtv_psi_eit_write_args args) while (event_descriptor) { /* copy the event descriptors, if any */ - d_args.dest_buf = args.buf; - d_args.dest_offset = args.offset + nbytes; + d_args.dest_offset = args->offset + nbytes; d_args.desc = event_descriptor; - d_args.pid = VIDTV_EIT_PID; - d_args.continuity_counter = args.continuity_counter; - d_args.dest_buf_sz = args.buf_sz; + d_args.continuity_counter = args->continuity_counter; d_args.crc = &crc; nbytes += vidtv_psi_desc_write_into(&d_args); @@ -1929,12 +1934,9 @@ u32 vidtv_psi_eit_write_into(struct vidtv_psi_eit_write_args args) event = event->next; } - c_args.dest_buf = args.buf; - c_args.dest_offset = args.offset + nbytes; + c_args.dest_offset = args->offset + nbytes; c_args.crc = cpu_to_be32(crc); - c_args.pid = VIDTV_EIT_PID; - c_args.continuity_counter = args.continuity_counter; - c_args.dest_buf_sz = args.buf_sz; + c_args.continuity_counter = args->continuity_counter; /* Write the CRC at the end */ nbytes += table_section_crc32_write_into(&c_args); diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.h b/drivers/media/test-drivers/vidtv/vidtv_psi.h index 8e366ea44cca..7a5901f11a37 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.h +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.h @@ -773,7 +773,7 @@ struct vidtv_psi_eit_write_args { * equal to the size of the EIT, since more space is needed for TS headers during TS * encapsulation. */ -u32 vidtv_psi_eit_write_into(struct vidtv_psi_eit_write_args args); +u32 vidtv_psi_eit_write_into(struct vidtv_psi_eit_write_args *args); void vidtv_psi_eit_table_destroy(struct vidtv_psi_table_eit *eit); -- cgit v1.2.3 From 020120af21a643c6adaa4f090c3abf275e3edd68 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 19 Nov 2020 12:17:49 +0100 Subject: media: vidtv.rst: update vidtv documentation Update the vidtv documentation with the relevant changes after the last patches. Signed-off-by: Mauro Carvalho Chehab --- Documentation/driver-api/media/drivers/vidtv.rst | 85 ++++++++++++++++++++---- 1 file changed, 72 insertions(+), 13 deletions(-) diff --git a/Documentation/driver-api/media/drivers/vidtv.rst b/Documentation/driver-api/media/drivers/vidtv.rst index edaceef2808c..52c201798d78 100644 --- a/Documentation/driver-api/media/drivers/vidtv.rst +++ b/Documentation/driver-api/media/drivers/vidtv.rst @@ -258,6 +258,42 @@ Using dvb-fe-tool The first step to check whether the demod loaded successfully is to run:: $ dvb-fe-tool + Device Dummy demod for DVB-T/T2/C/S/S2 (/dev/dvb/adapter0/frontend0) capabilities: + CAN_FEC_1_2 + CAN_FEC_2_3 + CAN_FEC_3_4 + CAN_FEC_4_5 + CAN_FEC_5_6 + CAN_FEC_6_7 + CAN_FEC_7_8 + CAN_FEC_8_9 + CAN_FEC_AUTO + CAN_GUARD_INTERVAL_AUTO + CAN_HIERARCHY_AUTO + CAN_INVERSION_AUTO + CAN_QAM_16 + CAN_QAM_32 + CAN_QAM_64 + CAN_QAM_128 + CAN_QAM_256 + CAN_QAM_AUTO + CAN_QPSK + CAN_TRANSMISSION_MODE_AUTO + DVB API Version 5.11, Current v5 delivery system: DVBC/ANNEX_A + Supported delivery systems: + DVBT + DVBT2 + [DVBC/ANNEX_A] + DVBS + DVBS2 + Frequency range for the current standard: + From: 51.0 MHz + To: 2.15 GHz + Step: 62.5 kHz + Tolerance: 29.5 MHz + Symbol rate ranges for the current standard: + From: 1.00 MBauds + To: 45.0 MBauds This should return what is currently set up at the demod struct, i.e.:: @@ -316,7 +352,7 @@ For this, one should provide a configuration file known as a 'scan file', here's an example:: [Channel] - FREQUENCY = 330000000 + FREQUENCY = 474000000 MODULATION = QAM/AUTO SYMBOL_RATE = 6940000 INNER_FEC = AUTO @@ -337,6 +373,14 @@ You can browse scan tables online here: `dvb-scan-tables Assuming this channel is named 'channel.conf', you can then run:: $ dvbv5-scan channel.conf + dvbv5-scan ~/vidtv.conf + ERROR command BANDWIDTH_HZ (5) not found during retrieve + Cannot calc frequency shift. Either bandwidth/symbol-rate is unavailable (yet). + Scanning frequency #1 330000000 + (0x00) Signal= -68.00dBm + Scanning frequency #2 474000000 + Lock (0x1f) Signal= -34.45dBm C/N= 33.74dB UCB= 0 + Service Beethoven, provider LinuxTV.org: digital television For more information on dvb-scan, check its documentation online here: `dvb-scan Documentation `_. @@ -346,23 +390,38 @@ Using dvb-zap dvbv5-zap is a command line tool that can be used to record MPEG-TS to disk. The typical use is to tune into a channel and put it into record mode. The example -below - which is taken from the documentation - illustrates that:: +below - which is taken from the documentation - illustrates that\ [1]_:: - $ dvbv5-zap -c dvb_channel.conf "trilhas sonoras" -r - using demux '/dev/dvb/adapter0/demux0' + $ dvbv5-zap -c dvb_channel.conf "beethoven" -o music.ts -P -t 10 + using demux 'dvb0.demux0' reading channels from file 'dvb_channel.conf' - service has pid type 05: 204 - tuning to 573000000 Hz - audio pid 104 - dvb_set_pesfilter 104 - Lock (0x1f) Quality= Good Signal= 100.00% C/N= -13.80dB UCB= 70 postBER= 3.14x10^-3 PER= 0 - DVR interface '/dev/dvb/adapter0/dvr0' can now be opened + tuning to 474000000 Hz + pass all PID's to TS + dvb_set_pesfilter 8192 + dvb_dev_set_bufsize: buffer set to 6160384 + Lock (0x1f) Quality= Good Signal= -34.66dBm C/N= 33.41dB UCB= 0 postBER= 0 preBER= 1.05x10^-3 PER= 0 + Lock (0x1f) Quality= Good Signal= -34.57dBm C/N= 33.46dB UCB= 0 postBER= 0 preBER= 1.05x10^-3 PER= 0 + Record to file 'music.ts' started + received 24587768 bytes (2401 Kbytes/sec) + Lock (0x1f) Quality= Good Signal= -34.42dBm C/N= 33.89dB UCB= 0 postBER= 0 preBER= 2.44x10^-3 PER= 0 -The channel can be watched by playing the contents of the DVR interface, with -some player that recognizes the MPEG-TS format, such as *mplayer* or *vlc*. +.. [1] In this example, it records 10 seconds with all program ID's stored + at the music.ts file. + + +The channel can be watched by playing the contents of the stream with some +player that recognizes the MPEG-TS format, such as ``mplayer`` or ``vlc``. By playing the contents of the stream one can visually inspect the workings of -vidtv, e.g.:: +vidtv, e.g., to play a recorded TS file with:: + + $ mplayer music.ts + +or, alternatively, running this command on one terminal:: + + $ dvbv5-zap -c dvb_channel.conf "beethoven" -P -r & + +And, on a second terminal, playing the contents from DVR interface with:: $ mplayer /dev/dvb/adapter0/dvr0 -- cgit v1.2.3 From 44f28934af141149959c4e6495bb60c1903bda32 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 24 Nov 2020 11:27:42 +0100 Subject: media: vidtv.rst: add kernel-doc markups Fix existing issues at the kernel-doc markups and add them to the vidtv.rst file. Signed-off-by: Mauro Carvalho Chehab --- Documentation/driver-api/media/drivers/vidtv.rst | 27 ++++++++++++++++ drivers/media/test-drivers/vidtv/vidtv_bridge.h | 2 +- drivers/media/test-drivers/vidtv/vidtv_channel.h | 1 + drivers/media/test-drivers/vidtv/vidtv_demod.h | 10 +++--- drivers/media/test-drivers/vidtv/vidtv_encoder.h | 4 ++- drivers/media/test-drivers/vidtv/vidtv_mux.h | 5 ++- drivers/media/test-drivers/vidtv/vidtv_pes.h | 5 ++- drivers/media/test-drivers/vidtv/vidtv_psi.h | 39 ++++++++++++------------ drivers/media/test-drivers/vidtv/vidtv_s302m.h | 5 ++- drivers/media/test-drivers/vidtv/vidtv_ts.h | 4 +-- 10 files changed, 70 insertions(+), 32 deletions(-) diff --git a/Documentation/driver-api/media/drivers/vidtv.rst b/Documentation/driver-api/media/drivers/vidtv.rst index 52c201798d78..673bdff919ea 100644 --- a/Documentation/driver-api/media/drivers/vidtv.rst +++ b/Documentation/driver-api/media/drivers/vidtv.rst @@ -484,3 +484,30 @@ A nice addition is to simulate some noise when the signal quality is bad by: - Updating the error statistics accordingly (e.g. BER, etc). - Simulating some noise in the encoded data. + +Functions and structs used within vidtv +--------------------------------------- + +.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_bridge.h + +.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_channel.h + +.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_demod.h + +.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_encoder.h + +.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_mux.h + +.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_pes.h + +.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_psi.h + +.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_s302m.h + +.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_ts.h + +.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_tuner.h + +.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_common.c + +.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_tuner.c diff --git a/drivers/media/test-drivers/vidtv/vidtv_bridge.h b/drivers/media/test-drivers/vidtv/vidtv_bridge.h index a85068bffd0f..2528adaee27d 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_bridge.h +++ b/drivers/media/test-drivers/vidtv/vidtv_bridge.h @@ -34,7 +34,7 @@ * @adapter: Represents a DTV adapter. See 'dvb_register_adapter'. * @demux: The demux used by the dvb_dmx_swfilter_packets() call. * @dmx_dev: Represents a demux device. - * @dmx_frontend: The frontends associated with the demux. + * @dmx_fe: The frontends associated with the demux. * @i2c_adapter: The i2c_adapter associated with the bridge driver. * @i2c_client_demod: The i2c_clients associated with the demodulator modules. * @i2c_client_tuner: The i2c_clients associated with the tuner modules. diff --git a/drivers/media/test-drivers/vidtv/vidtv_channel.h b/drivers/media/test-drivers/vidtv/vidtv_channel.h index 4bc2a4c0980d..fff2e501d375 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_channel.h +++ b/drivers/media/test-drivers/vidtv/vidtv_channel.h @@ -39,6 +39,7 @@ * Every stream will have its corresponding encoder polled to produce TS packets * These packets may be interleaved by the mux and then delivered to the bridge * + * @name: name of the channel * @transport_stream_id: a number to identify the TS, chosen at will. * @service: A _single_ service. Will be concatenated into the SDT. * @program_num: The link between PAT, PMT and SDT. diff --git a/drivers/media/test-drivers/vidtv/vidtv_demod.h b/drivers/media/test-drivers/vidtv/vidtv_demod.h index ab84044f33ba..2b8404661348 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_demod.h +++ b/drivers/media/test-drivers/vidtv/vidtv_demod.h @@ -20,6 +20,9 @@ * modulation and fec_inner * @modulation: see enum fe_modulation * @fec: see enum fe_fec_rate + * @cnr_ok: S/N threshold to consider the signal as OK. Below that, there's + * a chance of losing sync. + * @cnr_good: S/N threshold to consider the signal strong. * * This struct matches values for 'good' and 'ok' CNRs given the combination * of modulation and fec_inner in use. We might simulate some noise if the @@ -53,13 +56,8 @@ struct vidtv_demod_config { * struct vidtv_demod_state - The demodulator state * @frontend: The frontend structure allocated by the demod. * @config: The config used to init the demod. - * @poll_snr: The task responsible for periodically checking the simulated - * signal quality, eventually dropping or reacquiring the TS lock. * @status: the demod status. - * @cold_start: Whether the demod has not been init yet. - * @poll_snr_thread_running: Whether the task responsible for periodically - * checking the simulated signal quality is running. - * @poll_snr_thread_restart: Whether we should restart the poll_snr task. + * @tuner_cnr: current S/N ratio for the signal carrier */ struct vidtv_demod_state { struct dvb_frontend frontend; diff --git a/drivers/media/test-drivers/vidtv/vidtv_encoder.h b/drivers/media/test-drivers/vidtv/vidtv_encoder.h index 0ac5b1e3f666..50e3cf4eb4eb 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_encoder.h +++ b/drivers/media/test-drivers/vidtv/vidtv_encoder.h @@ -103,14 +103,16 @@ enum musical_notes { * @encoder_buf_sz: The encoder buffer size, in bytes * @encoder_buf_offset: Our byte position in the encoder buffer. * @sample_count: How many samples we have encoded in total. + * @access_units: encoder payload units, used for clock references * @src_buf: The source of raw data to be encoded, encoder might set a * default if null. + * @src_buf_sz: size of @src_buf. * @src_buf_offset: Our position in the source buffer. * @is_video_encoder: Whether this a video encoder (as opposed to audio) * @ctx: Encoder-specific state. * @stream_id: Examples: Audio streams (0xc0-0xdf), Video streams * (0xe0-0xef). - * @es_id: The TS PID to use for the elementary stream in this encoder. + * @es_pid: The TS PID to use for the elementary stream in this encoder. * @encode: Prepare enough AUs for the given amount of time. * @clear: Clear the encoder output. * @sync: Attempt to synchronize with this encoder. diff --git a/drivers/media/test-drivers/vidtv/vidtv_mux.h b/drivers/media/test-drivers/vidtv/vidtv_mux.h index e186094c4fb7..ad82eb72b841 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_mux.h +++ b/drivers/media/test-drivers/vidtv/vidtv_mux.h @@ -59,6 +59,7 @@ struct vidtv_mux_timing { * @pat: The PAT in use by the muxer. * @pmt_secs: The PMT sections in use by the muxer. One for each program in the PAT. * @sdt: The SDT in use by the muxer. + * @nit: The NIT in use by the muxer. * @eit: the EIT in use by the muxer. */ struct vidtv_mux_si { @@ -86,8 +87,10 @@ struct vidtv_mux_pid_ctx { /** * struct vidtv_mux - A muxer abstraction loosely based in libavcodec/mpegtsenc.c - * @mux_rate_kbytes_sec: The bit rate for the TS, in kbytes. + * @fe: The frontend structure allocated by the muxer. + * @dev: pointer to struct device. * @timing: Keeps track of timing related information. + * @mux_rate_kbytes_sec: The bit rate for the TS, in kbytes. * @pid_ctx: A hash table to keep track of per-PID metadata. * @on_new_packets_available_cb: A callback to inform of new TS packets ready. * @mux_buf: A pointer to a buffer for this muxer. TS packets are stored there diff --git a/drivers/media/test-drivers/vidtv/vidtv_pes.h b/drivers/media/test-drivers/vidtv/vidtv_pes.h index 99f45056adc2..963c59155e72 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_pes.h +++ b/drivers/media/test-drivers/vidtv/vidtv_pes.h @@ -113,8 +113,10 @@ struct pes_header_write_args { * @dest_buf_sz: The size of the dest_buffer * @pid: The PID to use for the TS packets. * @continuity_counter: Incremented on every new TS packet. - * @n_pes_h_s_bytes: Padding bytes. Might be used by an encoder if needed, gets + * @wrote_pes_header: Flag to indicate that the PES header was written + * @n_stuffing_bytes: Padding bytes. Might be used by an encoder if needed, gets * discarded by the decoder. + * @pcr: counter driven by a 27Mhz clock. */ struct pes_ts_header_write_args { void *dest_buf; @@ -145,6 +147,7 @@ struct pes_ts_header_write_args { * @dts: DTS value to send. * @n_pes_h_s_bytes: Padding bytes. Might be used by an encoder if needed, gets * discarded by the decoder. + * @pcr: counter driven by a 27Mhz clock. */ struct pes_write_args { void *dest_buf; diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.h b/drivers/media/test-drivers/vidtv/vidtv_psi.h index 7a5901f11a37..340c9fb8d583 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.h +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.h @@ -43,7 +43,7 @@ enum vidtv_psi_stream_types { STREAM_PRIVATE_DATA = 0x06, /* see ISO/IEC 13818-1 2000 p. 48 */ }; -/** +/* * struct vidtv_psi_desc - A generic PSI descriptor type. * The descriptor length is an 8-bit field specifying the total number of bytes of the data portion * of the descriptor following the byte defining the value of this field. @@ -55,7 +55,7 @@ struct vidtv_psi_desc { u8 data[]; } __packed; -/** +/* * struct vidtv_psi_desc_service - Service descriptor. * See ETSI EN 300 468 section 6.2.33. */ @@ -71,7 +71,7 @@ struct vidtv_psi_desc_service { char *service_name; } __packed; -/** +/* * struct vidtv_psi_desc_registration - A registration descriptor. * See ISO/IEC 13818-1 section 2.6.8 */ @@ -93,7 +93,7 @@ struct vidtv_psi_desc_registration { u8 additional_identification_info[]; } __packed; -/** +/* * struct vidtv_psi_desc_network_name - A network name descriptor * see ETSI EN 300 468 v1.15.1 section 6.2.27 */ @@ -110,7 +110,7 @@ struct vidtv_psi_desc_service_list_entry { struct vidtv_psi_desc_service_list_entry *next; } __packed; -/** +/* * struct vidtv_psi_desc_service_list - A service list descriptor * see ETSI EN 300 468 v1.15.1 section 6.2.35 */ @@ -121,7 +121,7 @@ struct vidtv_psi_desc_service_list { struct vidtv_psi_desc_service_list_entry *service_list; } __packed; -/** +/* * struct vidtv_psi_desc_short_event - A short event descriptor * see ETSI EN 300 468 v1.15.1 section 6.2.37 */ @@ -142,7 +142,7 @@ struct vidtv_psi_desc_short_event char *event_name, char *text); -/** +/* * struct vidtv_psi_table_header - A header that is present for all PSI tables. */ struct vidtv_psi_table_header { @@ -158,7 +158,7 @@ struct vidtv_psi_table_header { u8 last_section; /* last_section_number */ } __packed; -/** +/* * struct vidtv_psi_table_pat_program - A single program in the PAT * See ISO/IEC 13818-1 : 2000 p.43 */ @@ -168,7 +168,7 @@ struct vidtv_psi_table_pat_program { struct vidtv_psi_table_pat_program *next; } __packed; -/** +/* * struct vidtv_psi_table_pat - The Program Allocation Table (PAT) * See ISO/IEC 13818-1 : 2000 p.43 */ @@ -179,7 +179,7 @@ struct vidtv_psi_table_pat { struct vidtv_psi_table_pat_program *program; } __packed; -/** +/* * struct vidtv_psi_table_sdt_service - Represents a service in the SDT. * see ETSI EN 300 468 v1.15.1 section 5.2.3. */ @@ -193,7 +193,7 @@ struct vidtv_psi_table_sdt_service { struct vidtv_psi_table_sdt_service *next; } __packed; -/** +/* * struct vidtv_psi_table_sdt - Represents the Service Description Table * see ETSI EN 300 468 v1.15.1 section 5.2.3. */ @@ -205,7 +205,7 @@ struct vidtv_psi_table_sdt { struct vidtv_psi_table_sdt_service *service; } __packed; -/** +/* * enum service_running_status - Status of a SDT service. * see ETSI EN 300 468 v1.15.1 section 5.2.3 table 6. */ @@ -213,7 +213,7 @@ enum service_running_status { RUNNING = 0x4, }; -/** +/* * enum service_type - The type of a SDT service. * see ETSI EN 300 468 v1.15.1 section 6.2.33, table 81. */ @@ -223,7 +223,7 @@ enum service_type { DIGITAL_RADIO_SOUND_SERVICE = 0X2, }; -/** +/* * struct vidtv_psi_table_pmt_stream - A single stream in the PMT. * See ISO/IEC 13818-1 : 2000 p.46. */ @@ -235,7 +235,7 @@ struct vidtv_psi_table_pmt_stream { struct vidtv_psi_table_pmt_stream *next; } __packed; -/** +/* * struct vidtv_psi_table_pmt - The Program Map Table (PMT). * See ISO/IEC 13818-1 : 2000 p.46. */ @@ -477,7 +477,6 @@ struct vidtv_psi_desc *vidtv_psi_desc_clone(struct vidtv_psi_desc *desc); * vidtv_psi_create_sec_for_each_pat_entry - Create a PMT section for each * program found in the PAT * @pat: The PAT to look for programs. - * @s: The stream loop (one or more streams) * @pcr_pid: packet ID for the PCR to be used for the program described in this * PMT section */ @@ -595,9 +594,11 @@ u32 vidtv_psi_sdt_write_into(struct vidtv_psi_sdt_write_args *args); * @buf: The destination buffer. * @offset: The offset into the destination buffer. * @pmt: A pointer to the PMT. + * @pid: Program ID * @buf_sz: The size of the destination buffer. * @continuity_counter: A pointer to the CC. Incremented on every new packet. - * + * @pcr_pid: The TS PID used for the PSI packets. All channels will share the + * same PCR. */ struct vidtv_psi_pmt_write_args { char *buf; @@ -713,7 +714,7 @@ u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args *args); void vidtv_psi_nit_table_destroy(struct vidtv_psi_table_nit *nit); -/** +/* * struct vidtv_psi_desc_short_event - A short event descriptor * see ETSI EN 300 468 v1.15.1 section 6.2.37 */ @@ -748,7 +749,7 @@ struct vidtv_psi_table_eit * struct vidtv_psi_eit_write_args - Arguments for writing an EIT section * @buf: The destination buffer. * @offset: The offset into the destination buffer. - * @nit: A pointer to the NIT + * @eit: A pointer to the EIT * @buf_sz: The size of the destination buffer. * @continuity_counter: A pointer to the CC. Incremented on every new packet. * diff --git a/drivers/media/test-drivers/vidtv/vidtv_s302m.h b/drivers/media/test-drivers/vidtv/vidtv_s302m.h index e990b755bb20..9cc94e4a8924 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_s302m.h +++ b/drivers/media/test-drivers/vidtv/vidtv_s302m.h @@ -33,6 +33,9 @@ * @enc: A pointer to the containing encoder structure. * @frame_index: The current frame in a block * @au_count: The total number of access units encoded up to now + * @last_duration: Duration of the tone currently being played + * @note_offset: Position at the music tone array + * @last_tone: Tone currently being played */ struct vidtv_s302m_ctx { struct vidtv_encoder *enc; @@ -43,7 +46,7 @@ struct vidtv_s302m_ctx { enum musical_notes last_tone; }; -/** +/* * struct vidtv_smpte_s302m_es - s302m MPEG Elementary Stream header. * * See SMPTE 302M 2007 table 1. diff --git a/drivers/media/test-drivers/vidtv/vidtv_ts.h b/drivers/media/test-drivers/vidtv/vidtv_ts.h index 6b989a2c1433..10838a2b8389 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_ts.h +++ b/drivers/media/test-drivers/vidtv/vidtv_ts.h @@ -53,7 +53,7 @@ struct vidtv_mpeg_ts { * @dest_offset: The byte offset into the buffer. * @pid: The TS PID for the PCR packets. * @buf_sz: The size of the buffer in bytes. - * @countinuity_counter: The TS continuity_counter. + * @continuity_counter: The TS continuity_counter. * @pcr: A sample from the system clock. */ struct pcr_write_args { @@ -70,7 +70,7 @@ struct pcr_write_args { * @dest_buf: The buffer to write into. * @dest_offset: The byte offset into the buffer. * @buf_sz: The size of the buffer in bytes. - * @countinuity_counter: The TS continuity_counter. + * @continuity_counter: The TS continuity_counter. */ struct null_packet_write_args { void *dest_buf; -- cgit v1.2.3