Beispiel #1
0
/*****************************************************************************
 * 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);
    }
}
Beispiel #2
0
/** @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);
}