1 /* 2 * Copyright (c) 2011-2014 - Mauro Carvalho Chehab 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License as published by 6 * the Free Software Foundation version 2.1 of the License. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU Lesser General Public License for more details. 12 * 13 * You should have received a copy of the GNU Lesser General Public License 14 * along with this program; if not, write to the Free Software 15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 16 * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 17 */ 18 #ifndef _LIBSCAN_H 19 #define _LIBSCAN_H 20 21 #include <stdint.h> 22 #include <linux/dvb/dmx.h> 23 #include <libdvbv5/descriptors.h> 24 #include <libdvbv5/dvb-sat.h> 25 26 /** 27 * @file dvb-scan.h 28 * @ingroup frontend_scan 29 * @brief Provides interfaces to scan programs inside MPEG-TS digital TV streams. 30 * @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1) 31 * @author Mauro Carvalho Chehab 32 * 33 * @par Bug Report 34 * Please submit bug reports and patches to linux-media@vger.kernel.org 35 */ 36 37 /* According with ISO/IEC 13818-1:2007 */ 38 39 #define MAX_TABLE_SIZE 1024 * 1024 40 41 #ifdef __cplusplus 42 extern "C" { 43 #endif 44 45 struct dvb_entry; 46 47 /** 48 * @struct dvb_v5_descriptors_program 49 * @brief Associates PMT with PAT tables 50 * @ingroup frontend_scan 51 * 52 * @param pat_pgm pointer for PAT descriptor 53 * @param pmt pointer for PMT descriptor 54 */ 55 struct dvb_v5_descriptors_program { 56 struct dvb_table_pat_program *pat_pgm; 57 struct dvb_table_pmt *pmt; 58 }; 59 60 /** 61 * @struct dvb_v5_descriptors 62 * @brief Contains the descriptors needed to scan the Service ID and other relevant info at a MPEG-TS Digital TV stream 63 * @ingroup frontend_scan 64 * 65 * @param delivery_system Delivery system of the parsed MPEG-TS 66 * @param entry struct dvb_entry pointer (see dvb-file.h) 67 * @param pat PAT table descriptor pointer (table ID 0x00). 68 * @param vct VCT table descriptor pointer (either table ID 0xc8, 69 * for TVCT or table ID 0xc9, for CVCT) 70 * @param program PAT/PMT array associated programs found at MPEG-TS 71 * @param num_program Number of program entries at @ref program array. 72 * @param nit NIT table descriptor pointer for table ID 0x40. 73 * @param sdt SDT table descriptor pointer for table ID 0x42. 74 * @param other_nits Contains an array of pointers to the other NIT 75 * extension tables identified by table ID 0x41. 76 * @param num_other_nits Number of NIT tables at @ref other_nits array. 77 * @param other_sdts Contains an array of pointers to the other NIT 78 * extension tables identified by table ID 0x46. 79 * @param num_other_sdts Number of NIT tables at @ref other_sdts array. 80 * 81 * Those descriptors are filled by the scan routines when the tables are 82 * found. Otherwise, they're NULL. 83 * 84 * @note: Never alloc this struct yourself. This is meant to always be 85 * allocated via dvb_scan_alloc_handler_table() or via dvb_get_ts_tables(). 86 */ 87 struct dvb_v5_descriptors { 88 uint32_t delivery_system; 89 90 struct dvb_entry *entry; 91 unsigned num_entry; 92 93 struct dvb_table_pat *pat; 94 struct atsc_table_vct *vct; 95 struct dvb_v5_descriptors_program *program; 96 struct dvb_table_nit *nit; 97 struct dvb_table_sdt *sdt; 98 99 unsigned num_program; 100 101 struct dvb_table_nit **other_nits; 102 unsigned num_other_nits; 103 104 struct dvb_table_sdt **other_sdts; 105 unsigned num_other_sdts; 106 }; 107 108 /** 109 * @struct dvb_table_filter 110 * @brief Describes the PES filters used by DVB scan 111 * @ingroup frontend_scan 112 * 113 * @param tid Table ID 114 * @param pid Program ID 115 * @param ts_id Table section ID (for multisession filtering). If no 116 * specific table section is needed, -1 should be used 117 * @param table pointer to a pointer for the table struct to be filled 118 * @param allow_section_gaps Allow non-continuous section numbering 119 * @param priv Internal structure used inside the DVB core. shouldn't 120 * be touched externally. 121 */ 122 struct dvb_table_filter { 123 /* Input data */ 124 unsigned char tid; 125 uint16_t pid; 126 int ts_id; 127 void **table; 128 129 int allow_section_gaps; 130 131 /* 132 * Private temp data used by dvb_read_sections(). 133 * Should not be filled outside dvb-scan.c, as they'll be 134 * overrided 135 */ 136 void *priv; 137 }; 138 /** 139 * @brief deallocates all data associated with a table filter 140 * @ingroup frontend_scan 141 * 142 * @param sect table filter pointer 143 */ 144 void dvb_table_filter_free(struct dvb_table_filter *sect); 145 146 /** 147 * @brief read MPEG-TS tables that comes from a DTV card 148 * @ingroup frontend_scan 149 * 150 * @param parms pointer to struct dvb_v5_fe_parms created when the 151 * frontend is opened 152 * @param dmx_fd an opened demux file descriptor 153 * @param tid Table ID 154 * @param pid Program ID 155 * @param table pointer to a pointer for the table struct to be filled 156 * @param timeout Limit, in seconds, to read a MPEG-TS table 157 * 158 * This function is used to read the DVB tables by specifying a table ID and 159 * a program ID. The libdvbv5 should have a parser for the descriptors of the 160 * table type that should be parsed. 161 * The table will be automatically allocated on success. 162 * The function will read on the specified demux and return when reading is 163 * done or an error has occurred. If table is not NULL after the call, it has 164 * to be freed with the apropriate free table function (even if an error has 165 * occurred). 166 * 167 * If the application wants to abort the read operation, it can change the 168 * value of parms->p.abort to 1. 169 * 170 * Returns 0 on success or a negative error code. 171 * 172 * Example usage: 173 * @code 174 * struct dvb_table_pat *pat; 175 * int r = dvb_read_section( parms, dmx_fd, DVB_TABLE_PAT, DVB_TABLE_PAT_PID, 176 * (void **) &pat, 5 ); 177 * if (r < 0) 178 * dvb_logerr("error reading PAT table"); 179 * else { 180 * // do something with pat 181 * } 182 * if (pat) 183 * dvb_table_pat_free( pat ); 184 * @endcode 185 */ 186 int dvb_read_section(struct dvb_v5_fe_parms *parms, int dmx_fd, 187 unsigned char tid, uint16_t pid, void **table, 188 unsigned timeout); 189 190 /** 191 * @brief read MPEG-TS tables that comes from a DTV card 192 * with an specific table section ID 193 * @ingroup frontend_scan 194 * 195 * @param parms pointer to struct dvb_v5_fe_parms created when the 196 * frontend is opened 197 * @param dmx_fd an opened demux file descriptor 198 * @param tid Table ID 199 * @param pid Program ID 200 * @param ts_id Table section ID (for multisession filtering). If no 201 * specific table section is needed, -1 should be used 202 * @param table pointer to a pointer for the table struct to be filled 203 * @param timeout limit, in seconds, to read a MPEG-TS table 204 * 205 * This is a variant of dvb_read_section() that also seeks for an specific 206 * table section ID given by ts_id. 207 */ 208 int dvb_read_section_with_id(struct dvb_v5_fe_parms *parms, int dmx_fd, 209 unsigned char tid, uint16_t pid, int ts_id, 210 void **table, unsigned timeout); 211 212 /** 213 * @brief read MPEG-TS tables that comes from a DTV card 214 * @ingroup frontend_scan 215 * 216 * @param parms pointer to struct dvb_v5_fe_parms created when the 217 * frontend is opened 218 * @param dmx_fd an opened demux file descriptor 219 * @param sect section filter pointer 220 * @param timeout limit, in seconds, to read a MPEG-TS table 221 * 222 * This is a variant of dvb_read_section() that uses a struct dvb_table_filter 223 * to specify the filter to use. 224 */ 225 int dvb_read_sections(struct dvb_v5_fe_parms *parms, int dmx_fd, 226 struct dvb_table_filter *sect, 227 unsigned timeout); 228 229 /** 230 * @brief allocates a struct dvb_v5_descriptors 231 * @ingroup frontend_scan 232 * 233 * @param delivery_system Delivery system to be used on the table 234 * 235 * At success, returns a pointer. NULL otherwise. 236 */ 237 struct dvb_v5_descriptors *dvb_scan_alloc_handler_table(uint32_t delivery_system); 238 239 /** 240 * @brief frees a struct dvb_v5_descriptors 241 * @ingroup frontend_scan 242 * 243 * @param dvb_scan_handler pointer to the struct to be freed. 244 */ 245 void dvb_scan_free_handler_table(struct dvb_v5_descriptors *dvb_scan_handler); 246 247 /** 248 * @brief Scans a DVB stream, looking for the tables needed to 249 * identify the programs inside a MPEG-TS 250 * @ingroup frontend_scan 251 * 252 * @param parms pointer to struct dvb_v5_fe_parms created when 253 * the frontend is opened 254 * @param dmx_fd an opened demux file descriptor 255 * @param delivery_system delivery system to be scanned 256 * @param other_nit use alternate table IDs for NIT and other tables 257 * @param timeout_multiply improves the timeout for each table reception 258 * by using a value that will multiply the wait 259 * time. 260 * 261 * Given an opened frontend and demux, this function seeks for all programs 262 * available at the transport stream, and parses the following tables: 263 * PAT, PMT, NIT, SDT (and VCT, if the delivery system is ATSC). 264 * 265 * On sucess, it returns a pointer to a struct dvb_v5_descriptors, that can 266 * either be used to tune into a service or to be stored inside a file. 267 */ 268 struct dvb_v5_descriptors *dvb_get_ts_tables(struct dvb_v5_fe_parms *parms, int dmx_fd, 269 uint32_t delivery_system, 270 unsigned other_nit, 271 unsigned timeout_multiply); 272 273 /** 274 * @brief frees a struct dvb_v5_descriptors 275 * @ingroup frontend_scan 276 * 277 * @param dvb_desc pointed to the structure to be freed. 278 * 279 * This function recursively frees everything that is allocated by 280 * dvb_get_ts_tables() and stored at dvb_desc, including dvb_desc itself. 281 */ 282 void dvb_free_ts_tables(struct dvb_v5_descriptors *dvb_desc); 283 284 /** 285 * @brief Callback for the application to show the frontend status 286 * @ingroup frontend_scan 287 * 288 * @param args a pointer, opaque to libdvbv5, to be used by the 289 * application if needed. 290 * @param parms pointer to struct dvb_v5_fe_parms created when the 291 * frontend is opened 292 */ 293 typedef int (check_frontend_t)(void *args, struct dvb_v5_fe_parms *parms); 294 295 /** 296 * @brief Scans a DVB dvb_add_scaned_transponder 297 * @ingroup frontend_scan 298 * 299 * @param parms pointer to struct dvb_v5_fe_parms created when the 300 * frontend is opened 301 * @param entry DVB file entry that corresponds to a transponder to be 302 * tuned 303 * @param dmx_fd an opened demux file descriptor 304 * @param check_frontend a pointer to a function that will show the frontend 305 * status while tuning into a transponder 306 * @param args a pointer, opaque to libdvbv5, that will be used when 307 * calling check_frontend. It should contain any parameters 308 * that could be needed by check_frontend. 309 * @param other_nit Use alternate table IDs for NIT and other tables 310 * @param timeout_multiply Improves the timeout for each table reception, by 311 * 312 * This is the function that applications should use when doing a transponders 313 * scan. It does everything needed to fill the entries with DVB programs 314 * (virtual channels) and detect the PIDs associated with them. 315 * 316 * A typical usage is to after open a channel file, open a dmx_fd and open 317 * a frontend. Then, seek for the MPEG tables on all the transponder 318 * frequencies with: 319 * 320 * @code 321 * for (entry = dvb_file->first_entry; entry != NULL; entry = entry->next) { 322 * struct dvb_v5_descriptors *dvb_scan_handler = NULL; 323 * 324 * dvb_scan_handler = dvb_scan_transponder(parms, entry, dmx_fd, 325 * &check_frontend, args, 326 * args->other_nit, 327 * args->timeout_multiply); 328 * if (parms->abort) { 329 * dvb_scan_free_handler_table(dvb_scan_handler); 330 * break; 331 * } 332 * if (dvb_scan_handler) { 333 * dvb_store_channel(&dvb_file_new, parms, dvb_scan_handler, 334 * args->get_detected, args->get_nit); 335 * dvb_scan_free_handler_table(dvb_scan_handler); 336 * } 337 * } 338 * @endcode 339 */ 340 struct dvb_v5_descriptors *dvb_scan_transponder(struct dvb_v5_fe_parms *parms, 341 struct dvb_entry *entry, 342 int dmx_fd, 343 check_frontend_t *check_frontend, 344 void *args, 345 unsigned other_nit, 346 unsigned timeout_multiply); 347 348 349 /** 350 * @brief Add new transponders to a dvb_file 351 * @ingroup frontend_scan 352 * 353 * @param parms pointer to struct dvb_v5_fe_parms created when the 354 * frontend is opened 355 * @param dvb_scan_handler pointer to a struct dvb_v5_descriptors containing 356 * scaned MPEG-TS 357 * @param first_entry first entry of a DVB file struct 358 * @param entry current entry on a DVB file struct 359 * 360 * When the NIT table is parsed, some new transponders could be described 361 * inside. This function adds new entries to a dvb_file struct, pointing 362 * to those new transponders. It is used inside the scan loop, as shown at 363 * the dvb_scan_transponder(), to add new channels. 364 * 365 * Example: 366 * @code 367 * for (entry = dvb_file->first_entry; entry != NULL; entry = entry->next) { 368 * struct dvb_v5_descriptors *dvb_scan_handler = NULL; 369 * 370 * dvb_scan_handler = dvb_scan_transponder(parms, entry, dmx_fd, 371 * &check_frontend, args, 372 * args->other_nit, 373 * args->timeout_multiply); 374 * if (parms->abort) { 375 * dvb_scan_free_handler_table(dvb_scan_handler); 376 * break; 377 * } 378 * if (dvb_scan_handler) { 379 * dvb_store_channel(&dvb_file_new, parms, dvb_scan_handler, 380 * args->get_detected, args->get_nit); 381 * dvb_scan_free_handler_table(dvb_scan_handler); 382 * 383 * dvb_add_scaned_transponders(parms, dvb_scan_handler, 384 * dvb_file->first_entry, entry); 385 * 386 * dvb_scan_free_handler_table(dvb_scan_handler); 387 * } 388 * } 389 * @endcode 390 */ 391 void dvb_add_scaned_transponders(struct dvb_v5_fe_parms *parms, 392 struct dvb_v5_descriptors *dvb_scan_handler, 393 struct dvb_entry *first_entry, 394 struct dvb_entry *entry); 395 396 #ifndef _DOXYGEN 397 /* 398 * Some ancillary functions used internally inside the library, used to 399 * identify duplicated transport streams and add new found transponder entries 400 */ 401 int dvb_estimate_freq_shift(struct dvb_v5_fe_parms *parms); 402 403 int dvb_new_freq_is_needed(struct dvb_entry *entry, struct dvb_entry *last_entry, 404 uint32_t freq, enum dvb_sat_polarization pol, int shift); 405 406 struct dvb_entry *dvb_scan_add_entry(struct dvb_v5_fe_parms *parms, 407 struct dvb_entry *first_entry, 408 struct dvb_entry *entry, 409 uint32_t freq, uint32_t shift, 410 enum dvb_sat_polarization pol); 411 412 int dvb_new_entry_is_needed(struct dvb_entry *entry, 413 struct dvb_entry *last_entry, 414 uint32_t freq, int shift, 415 enum dvb_sat_polarization pol, uint32_t stream_id); 416 417 struct dvb_entry *dvb_scan_add_entry_ex(struct dvb_v5_fe_parms *parms, 418 struct dvb_entry *first_entry, 419 struct dvb_entry *entry, 420 uint32_t freq, uint32_t shift, 421 enum dvb_sat_polarization pol, 422 uint32_t stream_id); 423 424 void dvb_update_transponders(struct dvb_v5_fe_parms *parms, 425 struct dvb_v5_descriptors *dvb_scan_handler, 426 struct dvb_entry *first_entry, 427 struct dvb_entry *entry); 428 #endif 429 430 #ifdef __cplusplus 431 } 432 #endif 433 434 #endif 435