/***************************************************************************** * handle_section *****************************************************************************/ static void handle_section(uint16_t i_pid, uint8_t *p_section) { uint8_t i_table_id = psi_get_tableid(p_section); if (!psi_validate(p_section)) { printf("<ERROR type=\"invalid_section\" pid=\"%hu\"/>\n", i_pid); free(p_section); return; } switch (i_table_id) { case PAT_TABLE_ID: handle_pat_section(i_pid, p_section); break; case TSDT_TABLE_ID: handle_tsdt_section(i_pid, p_section); break; case PMT_TABLE_ID: handle_pmt(i_pid, p_section); break; case NIT_TABLE_ID_ACTUAL: handle_nit_section(i_pid, p_section); break; case SDT_TABLE_ID_ACTUAL: handle_sdt_section(i_pid, p_section); break; default: free( p_section ); break; } }
/** @internal @This merges a PSI section. * * @param upipe description structure of the pipe * @param uref uref pointing to (part of) a PSI section * @param upump_p reference to pump that generated the buffer * @return false if the uref has been entirely consumed */ static bool upipe_ts_psim_merge(struct upipe *upipe, struct uref *uref, struct upump **upump_p) { struct upipe_ts_psim *upipe_ts_psim = upipe_ts_psim_from_upipe(upipe); if (upipe_ts_psim->next_uref != NULL) { struct ubuf *ubuf = ubuf_dup(uref->ubuf); if (unlikely(ubuf == NULL || !ubase_check(uref_block_append(upipe_ts_psim->next_uref, ubuf)))) { upipe_ts_psim_flush(upipe); if (ubuf != NULL) ubuf_free(ubuf); upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return false; } } else { /* Check for stuffing */ uint8_t table_id; if (unlikely(!ubase_check(uref_block_extract(uref, 0, 1, &table_id)) || table_id == 0xff)) { return false; } upipe_ts_psim->next_uref = uref_dup(uref); if (unlikely(upipe_ts_psim->next_uref == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return false; } } size_t size = 0; UBASE_FATAL(upipe, uref_block_size(upipe_ts_psim->next_uref, &size)) if (size < PSI_HEADER_SIZE) return false; uint8_t buffer[PSI_HEADER_SIZE]; const uint8_t *psi_header = uref_block_peek(upipe_ts_psim->next_uref, 0, PSI_HEADER_SIZE, buffer); assert(psi_header != NULL); uint16_t length = psi_get_length(psi_header); UBASE_FATAL(upipe, uref_block_peek_unmap(upipe_ts_psim->next_uref, 0, buffer, psi_header)); if (unlikely(!psi_validate(psi_header) || length + PSI_HEADER_SIZE > PSI_PRIVATE_MAX_SIZE)) { upipe_warn(upipe, "wrong PSI header"); upipe_ts_psim_flush(upipe); return false; } if (length + PSI_HEADER_SIZE > size) return false; UBASE_FATAL(upipe, uref_block_resize(upipe_ts_psim->next_uref, 0, length + PSI_HEADER_SIZE)); upipe_ts_psim_output(upipe, upipe_ts_psim->next_uref, upump_p); upipe_ts_psim->next_uref = NULL; if (length + PSI_HEADER_SIZE == size) return false; size_t uref_size = 0; UBASE_FATAL(upipe, uref_block_size(uref, &uref_size)) UBASE_FATAL(upipe, uref_block_resize(uref, length + PSI_HEADER_SIZE - (size - uref_size), -1)); return true; }