/***************************************************************************** * handle_psi_packet *****************************************************************************/ static void handle_psi_packet(uint8_t *p_ts) { uint16_t i_pid = ts_get_pid(p_ts); ts_pid_t *p_pid = &p_pids[i_pid]; uint8_t i_cc = ts_get_cc(p_ts); const uint8_t *p_payload; uint8_t i_length; if (ts_check_duplicate(i_cc, p_pid->i_last_cc) || !ts_has_payload(p_ts)) return; if (p_pid->i_last_cc != -1 && ts_check_discontinuity(i_cc, p_pid->i_last_cc)) psi_assemble_reset(&p_pid->p_psi_buffer, &p_pid->i_psi_buffer_used); p_payload = ts_section(p_ts); i_length = p_ts + TS_SIZE - p_payload; if (!psi_assemble_empty(&p_pid->p_psi_buffer, &p_pid->i_psi_buffer_used)) { uint8_t *p_section = psi_assemble_payload(&p_pid->p_psi_buffer, &p_pid->i_psi_buffer_used, &p_payload, &i_length); if (p_section != NULL) handle_section(i_pid, p_section); } p_payload = ts_next_section( p_ts ); i_length = p_ts + TS_SIZE - p_payload; while (i_length) { uint8_t *p_section = psi_assemble_payload(&p_pid->p_psi_buffer, &p_pid->i_psi_buffer_used, &p_payload, &i_length); if (p_section != NULL) handle_section(i_pid, p_section); } }
/** @internal @This handles input buffers. * * @param upipe description structure of the pipe * @param uref input buffer to handle * @param upump_p reference to the pump that generated the buffer */ static void upipe_dvbcsa_enc_input(struct upipe *upipe, struct uref *uref, struct upump **upump_p) { struct upipe_dvbcsa_enc *upipe_dvbcsa_enc = upipe_dvbcsa_enc_from_upipe(upipe); struct upipe_dvbcsa_common *common = upipe_dvbcsa_enc_to_common(upipe_dvbcsa_enc); if (unlikely(!upipe_dvbcsa_enc->key)) /* no key set, forward */ return upipe_dvbcsa_enc_output(upipe, uref, upump_p); uint32_t ts_header_size = TS_HEADER_SIZE; uint8_t buf[TS_HEADER_SIZE]; const uint8_t *ts_header = uref_block_peek(uref, 0, sizeof (buf), buf); if (unlikely(!ts_header)) { upipe_err(upipe, "fail to read ts header"); uref_free(uref); return; } uint8_t scrambling = ts_get_scrambling(ts_header); bool has_payload = ts_has_payload(ts_header); bool has_adaptation = ts_has_adaptation(ts_header); uint16_t pid = ts_get_pid(ts_header); uref_block_peek_unmap(uref, 0, buf, ts_header); if (!has_payload || scrambling || !upipe_dvbcsa_common_check_pid(common, pid)) return upipe_dvbcsa_enc_output(upipe, uref, upump_p); if (unlikely(has_adaptation)) { uint8_t af_length; int ret = uref_block_extract(uref, ts_header_size, 1, &af_length); if (unlikely(!ubase_check(ret))) { upipe_err(upipe, "fail to extract adaptation field length"); uref_free(uref); return; } if (unlikely(af_length >= 183)) { upipe_warn(upipe, "invalid adaptation field received"); uref_free(uref); return; } ts_header_size += af_length + 1; } struct ubuf *ubuf = ubuf_block_copy(uref->ubuf->mgr, uref->ubuf, 0, -1); if (unlikely(!ubuf)) { upipe_err(upipe, "fail to allocate buffer"); uref_free(uref); return; } uref_attach_ubuf(uref, ubuf); int size = -1; uint8_t *ts; int ret = ubuf_block_write(ubuf, 0, &size, &ts); if (unlikely(!ubase_check(ret))) { upipe_err(upipe, "fail to write buffer"); uref_free(uref); return; } ts_set_scrambling(ts, 0x2); dvbcsa_encrypt(upipe_dvbcsa_enc->key, ts + ts_header_size, size - ts_header_size); return upipe_dvbcsa_enc_output(upipe, uref, upump_p); }