Пример #1
0
/** @internal @This handles input.
 *
 * @param upipe description structure of the pipe
 * @param uref uref structure
 * @param upump_p reference to upump structure
 */
static void upipe_osx_audioqueue_sink_input(struct upipe *upipe,
        struct uref *uref, struct upump **upump_p)
{
    struct upipe_osx_audioqueue_sink *osx_audioqueue =
        upipe_osx_audioqueue_sink_from_upipe(upipe);

    /* empty uref */
    if (unlikely(!uref->ubuf)) {
        uref_free(uref);
        return;
    }

    /* check queue */
    if (unlikely(!osx_audioqueue->queue)) {
        upipe_warn(upipe, "audioqueue not configured");
        uref_free(uref);
        return;
    }

    upipe_osx_audioqueue_sink_input_audio(upipe, uref, upump_p);
}
Пример #2
0
/** @internal @This flushes all input buffers.
 *
 * @param upipe description structure of the pipe
 * @param lost true if the sync was lost
 */
static void upipe_ts_pesd_flush(struct upipe *upipe, bool lost)
{
    struct upipe_ts_pesd *upipe_ts_pesd = upipe_ts_pesd_from_upipe(upipe);
    if (upipe_ts_pesd->next_uref != NULL) {
        uref_free(upipe_ts_pesd->next_uref);
        upipe_ts_pesd->next_uref = NULL;
        upipe_ts_pesd->next_uref_size = 0;
    }
    if (lost)
        upipe_ts_pesd_sync_lost(upipe);
    upipe_ts_pesd->drop = true;
}
Пример #3
0
/** @internal @This tries to find TS packets in the buffered input urefs.
 *
 * @param upipe description structure of the pipe
 * @param uref uref structure
 * @param upump_p reference to pump that generated the buffer
 */
static void upipe_ts_check_input(struct upipe *upipe, struct uref *uref,
                                 struct upump **upump_p)
{
    struct upipe_ts_check *upipe_ts_check = upipe_ts_check_from_upipe(upipe);
    size_t size;
    if (unlikely(!ubase_check(uref_block_size(uref, &size)))) {
        uref_free(uref);
        upipe_throw_fatal(upipe, UBASE_ERR_ALLOC);
        return;
    }

    bool first = true;
    while (size > upipe_ts_check->output_size) {
        struct uref *output = uref_block_splice(uref, 0,
                                                upipe_ts_check->output_size);
        if (unlikely(output == NULL)) {
            uref_free(uref);
            upipe_throw_fatal(upipe, UBASE_ERR_ALLOC);
            return;
        }

        if (!first)
            uref_flow_delete_discontinuity(output);
        first = false;

        if (!upipe_ts_check_check(upipe, output, upump_p)) {
            uref_free(uref);
            return;
        }

        uref_block_resize(uref, upipe_ts_check->output_size, -1);
        size -= upipe_ts_check->output_size;
    }

    if (!first)
        uref_flow_delete_discontinuity(uref);

    if (size == upipe_ts_check->output_size)
        upipe_ts_check_check(upipe, uref, upump_p);
}
Пример #4
0
/** @internal @This handles input.
 *
 * @param upipe description structure of the pipe
 * @param uref uref structure
 * @param upump_p reference to upump structure
 */
static void upipe_filter_ebur128_input(struct upipe *upipe, struct uref *uref,
                                       struct upump **upump_p)
{
    struct upipe_filter_ebur128 *upipe_filter_ebur128 =
                                 upipe_filter_ebur128_from_upipe(upipe);
    double loud = 0, lra = 0, global = 0;
    size_t samples;
    if (unlikely(!ubase_check(uref_sound_size(uref, &samples, NULL)))) {
        upipe_warn(upipe, "invalid sound buffer");
        uref_free(uref);
        return;
    }
    const char *channel = NULL;
    const int16_t *buf = NULL;
    if (ubase_check(uref_sound_plane_iterate(uref, &channel)) && channel) {
        if (unlikely(!ubase_check(uref_sound_plane_read_int16_t(uref,
                channel, 0, -1, &buf)))) {
            upipe_warn(upipe, "error mapping sound buffer");
            uref_free(uref);
            return;
        }

        if (unlikely((uintptr_t)buf & 1)) {
            upipe_warn(upipe, "unaligned buffer");
        }
        ebur128_add_frames_short(upipe_filter_ebur128->st, buf, samples);
        uref_sound_plane_unmap(uref, channel, 0, -1);
    }
    ebur128_loudness_momentary(upipe_filter_ebur128->st, &loud);
    ebur128_loudness_range(upipe_filter_ebur128->st, &lra);
    ebur128_loudness_global(upipe_filter_ebur128->st, &global);

    uref_ebur128_set_momentary(uref, loud);
    uref_ebur128_set_lra(uref, lra);
    uref_ebur128_set_global(uref, global);

    upipe_verbose_va(upipe, "loud %f lra %f global %f", loud, lra, global);

    upipe_filter_ebur128_output(upipe, uref, upump_p);
}
Пример #5
0
/** @This frees a upipe.
 *
 * @param urefcount_real pointer to urefcount_real structure
 */
static void upipe_fdec_free(struct urefcount *urefcount_real)
{
    struct upipe_fdec *upipe_fdec =
        upipe_fdec_from_urefcount_real(urefcount_real);
    struct upipe *upipe = upipe_fdec_to_upipe(upipe_fdec);
    upipe_throw_dead(upipe);
    uref_free(upipe_fdec->options);
    upipe_fdec_clean_last_inner_probe(upipe);
    upipe_fdec_clean_uref_mgr(upipe);
    urefcount_clean(urefcount_real);
    upipe_fdec_clean_urefcount(upipe);
    upipe_fdec_free_void(upipe);
}
Пример #6
0
/** @internal @This sets the input flow definition.
 *
 * @param upipe description structure of the pipe
 * @param flow_def flow definition packet
 * @return an error code
 */
static int upipe_rtpd_set_flow_def(struct upipe *upipe, struct uref *flow_def)
{
    if (flow_def == NULL)
        return UBASE_ERR_INVALID;
    UBASE_RETURN(uref_flow_match_def(flow_def, EXPECTED_FLOW_DEF))
    struct uref *flow_def_dup;
    if (unlikely((flow_def_dup = uref_dup(flow_def)) == NULL))
        return UBASE_ERR_ALLOC;
    struct upipe_rtpd *upipe_rtpd = upipe_rtpd_from_upipe(upipe);
    uref_free(upipe_rtpd->flow_def_input);
    upipe_rtpd->flow_def_input = flow_def_dup;
    return UBASE_ERR_NONE;
}
Пример #7
0
/** @This frees a upipe.
 *
 * @param upipe description structure of the pipe
 */
static void upipe_ts_pesd_free(struct upipe *upipe)
{
    struct upipe_ts_pesd *upipe_ts_pesd = upipe_ts_pesd_from_upipe(upipe);
    upipe_throw_dead(upipe);

    upipe_ts_pesd_clean_output(upipe);
    upipe_ts_pesd_clean_sync(upipe);

    if (upipe_ts_pesd->next_uref != NULL)
        uref_free(upipe_ts_pesd->next_uref);
    upipe_ts_pesd_clean_urefcount(upipe);
    upipe_ts_pesd_free_void(upipe);
}
Пример #8
0
/** @internal @This handles input.
 *
 * @param upipe description structure of the pipe
 * @param uref uref structure
 * @param upump pump that generated the buffer
 */
static void upipe_skip_input(struct upipe *upipe, struct uref *uref,
                               struct upump *upump)
{
    struct upipe_skip *upipe_skip = upipe_skip_from_upipe(upipe);
    const char *def;

    if (unlikely(uref_flow_get_def(uref, &def))) {
        if (unlikely(ubase_ncmp(def, EXPECTED_FLOW))) {
            upipe_throw_flow_def_error(upipe, uref);
            uref_free(uref);
            return;
        }

        upipe_dbg_va(upipe, "flow definition %s", def);
        if (unlikely(!uref_flow_set_def(uref, "block.")))
            upipe_throw_aerror(upipe);
        upipe_skip_store_flow_def(upipe, uref);
        return;
    }

    if (unlikely(uref_flow_get_end(uref))) {
        uref_free(uref);
        upipe_throw_need_input(upipe);
        return;
    }

    if (unlikely(upipe_skip->flow_def == NULL)) {
        upipe_throw_flow_def_error(upipe, uref);
        uref_free(uref);
        return;
    }

    if (unlikely(uref->ubuf == NULL)) {
        uref_free(uref);
        return;
    }

    upipe_skip_input_block(upipe, uref, upump);
}
Пример #9
0
/** @internal @This takes the payload of a TS packet, checks if it may
 * contain part of a PES header, and outputs it.
 *
 * @param upipe description structure of the pipe
 * @param uref uref structure
 * @param upump_p reference to pump that generated the buffer
 */
static void upipe_ts_pesd_input(struct upipe *upipe, struct uref *uref,
                                struct upump **upump_p)
{
    struct upipe_ts_pesd *upipe_ts_pesd = upipe_ts_pesd_from_upipe(upipe);
    size_t uref_size;
    if (unlikely(!ubase_check(uref_block_size(uref, &uref_size)))) {
        upipe_warn(upipe, "invalid PES chunk");
        uref_free(uref);
        return;
    }

    if (ubase_check(uref_block_get_start(uref))) {
        if (unlikely(upipe_ts_pesd->next_uref != NULL)) {
            upipe_warn(upipe, "truncated PES header");
            uref_free(upipe_ts_pesd->next_uref);
        }
        upipe_ts_pesd->next_uref = uref;
        upipe_ts_pesd->next_uref_size = uref_size;
        upipe_ts_pesd_decaps(upipe, upump_p);

    } else if (upipe_ts_pesd->next_uref != NULL) {
        struct ubuf *ubuf = uref_detach_ubuf(uref);
        uref_free(uref);
        if (unlikely(!ubase_check(uref_block_append(upipe_ts_pesd->next_uref,
                                                    ubuf)))) {
            ubuf_free(ubuf);
            upipe_ts_pesd_flush(upipe);
            upipe_throw_fatal(upipe, UBASE_ERR_ALLOC);
            return;
        }
        upipe_ts_pesd->next_uref_size += uref_size;
        upipe_ts_pesd_decaps(upipe, upump_p);
    } else if (likely(upipe_ts_pesd->acquired)) {
        upipe_ts_pesd->next_uref = uref;
        upipe_ts_pesd->next_uref_size += uref_size;
        upipe_ts_pesd_check_output(upipe, upump_p);
    } else
        uref_free(uref);
}
Пример #10
0
/** @internal @This handles input buffer of the blank source pipe. This buffer
 * is supposed to be a picture or a sound to set as source buffer of the blank
 * pipes (audio/video blank pipe generator).
 *
 * @param upipe description structure of the pipe
 * @param uref uref reference picture or sound
 * @param upump_p is ignored
 */
static void upipe_blksrc_input(struct upipe *upipe,
                               struct uref *uref,
                               struct upump **upump_p)
{
    struct upipe_blksrc *upipe_blksrc = upipe_blksrc_from_upipe(upipe);
    if (unlikely(!upipe_blksrc->flow_def)) {
        upipe_warn(upipe, "flow def is not set");
        uref_free(uref);
    }
    else if (ubase_check(uref_flow_match_def(upipe_blksrc->flow_def,
                                             UREF_PIC_FLOW_DEF))) {
        upipe_dbg(upipe, "set picture buffer");
        upipe_vblk_set_pic(upipe_blksrc->blk, uref);
    }
    else if (ubase_check(uref_flow_match_def(upipe_blksrc->flow_def,
                                             UREF_SOUND_FLOW_DEF)))
        upipe_ablk_set_sound(upipe_blksrc->blk, uref);
    else {
        upipe_warn(upipe, "unsupported flow definition");
        uref_free(uref);
    }
}
Пример #11
0
/** @This frees a upipe.
 *
 * @param upipe description structure of the pipe
 */
static void upipe_audiobar_free(struct upipe *upipe)
{
    upipe_throw_dead(upipe);

    struct upipe_audiobar *upipe_audiobar = upipe_audiobar_from_upipe(upipe);
    uref_free(upipe_audiobar->flow_def_config);
    upipe_audiobar_clean_flow_format(upipe);
    upipe_audiobar_clean_ubuf_mgr(upipe);
    upipe_audiobar_clean_output(upipe);
    upipe_audiobar_clean_input(upipe);
    upipe_audiobar_clean_urefcount(upipe);
    upipe_audiobar_free_flow(upipe);
}
Пример #12
0
/** @This frees a upipe.
 *
 * @param upipe description structure of the pipe
 */
static void upipe_telxf_free(struct upipe *upipe)
{
    struct upipe_telxf *upipe_telxf = upipe_telxf_from_upipe(upipe);
    upipe_throw_dead(upipe);

    uref_free(upipe_telxf->next_uref);
    upipe_telxf_clean_output(upipe);
    upipe_telxf_clean_flow_def(upipe);
    upipe_telxf_clean_sync(upipe);

    upipe_telxf_clean_urefcount(upipe);
    upipe_telxf_free_void(upipe);
}
Пример #13
0
/** @internal @This allocates a block_to_sound pipe.
 *
 * @param mgr common management structure
 * @param uprobe structure used to raise events
 * @param signature signature of the pipe allocator
 * @param args optional arguments
 * @return pointer to upipe or NULL in case of allocation error
 */
static struct upipe *upipe_block_to_sound_alloc(struct upipe_mgr *mgr,
                                      struct uprobe *uprobe,
                                      uint32_t signature, va_list args)
{
    struct uref *flow_def;

    struct upipe *upipe = upipe_block_to_sound_alloc_flow(mgr, uprobe, signature, args, &flow_def);
    if (unlikely(upipe == NULL))
        return NULL;

    struct upipe_block_to_sound *upipe_block_to_sound = upipe_block_to_sound_from_upipe(upipe);

    if (unlikely(!ubase_check(uref_sound_flow_get_planes(flow_def,
            &upipe_block_to_sound->planes)) || upipe_block_to_sound->planes != 1 )) {
        upipe_err_va(upipe, "wrong number of planes: %d", upipe_block_to_sound->planes);
        upipe_block_to_sound_free_flow(upipe);
        uref_free(flow_def);
        return NULL;
    }

    if (unlikely(!ubase_check(uref_sound_flow_get_sample_size(flow_def,
            &upipe_block_to_sound->sample_size)))) {
        upipe_err_va(upipe, "flow def needs sample_size");
        upipe_block_to_sound_free_flow(upipe);
        uref_free(flow_def);
        return NULL;
    }

    upipe_block_to_sound->flow_def_config = flow_def;

    upipe_block_to_sound_init_urefcount(upipe);
    upipe_block_to_sound_init_output(upipe);
    upipe_block_to_sound_init_ubuf_mgr(upipe);

    upipe_throw_ready(upipe);

    return upipe;
}
Пример #14
0
/** @internal @This inputs data.
 *
 * @param upipe description structure of the pipe
 * @param uref uref structure
 * @param upump_p reference to upump structure
 */
static void upipe_nacl_audio_input(struct upipe *upipe, struct uref *uref, 
                                   struct upump **upump_p)
{    
    struct upipe_nacl_audio *upipe_nacl_audio =
        upipe_nacl_audio_from_upipe(upipe);
    size_t uref_size;
    if (unlikely(!ubase_check(uref_sound_size(uref, &uref_size, NULL)))) {
        upipe_warn(upipe, "unable to read uref");
        uref_free(uref);
        return;
    }

    if (unlikely(!upipe_nacl_audio->started && !upipe_nacl_audio_open(upipe))) {
        upipe_warn(upipe, "unable to open device");
        uref_free(uref);
        return;
    }

    uint64_t uref_pts;
    if (likely(ubase_check(uref_clock_get_pts_sys(uref, &uref_pts)))) {
        uref_pts += upipe_nacl_audio->latency;
        uref_clock_set_pts_sys(uref, uref_pts);
    }

    if (!upipe_nacl_audio_check_input(upipe)) {
        upipe_nacl_audio_hold_input(upipe, uref);
        upipe_nacl_audio_block_input(upipe, upump_p);
    } else if (!upipe_nacl_audio_handle(upipe, uref, upump_p)) {
        if (!upipe_nacl_audio_check_watcher(upipe)) {
            upipe_warn(upipe, "unable to spool uref");
            uref_free(uref);
            return;
        }
        upipe_nacl_audio_hold_input(upipe, uref);
        upipe_nacl_audio_block_input(upipe, upump_p);
        upump_start(upipe_nacl_audio->upump);
    }
}
Пример #15
0
/** @internal @This checks the presence of the sync word.
 *
 * @param upipe description structure of the pipe
 * @param uref uref structure
 * @param upump_p reference to pump that generated the buffer
 */
static bool upipe_ts_check_check(struct upipe *upipe, struct uref *uref,
                                 struct upump **upump_p)
{
    const uint8_t *buffer;
    int size = 1;
    uint8_t word;
    if (unlikely(!ubase_check(uref_block_read(uref, 0, &size, &buffer)))) {
        uref_free(uref);
        upipe_throw_fatal(upipe, UBASE_ERR_ALLOC);
        return false;
    }
    assert(size == 1);
    word = *buffer;
    uref_block_unmap(uref, 0);
    if (word != TS_SYNC) {
        uref_free(uref);
        upipe_warn_va(upipe, "invalid TS sync 0x%"PRIx8, word);
        return false;
    }

    upipe_ts_check_output(upipe, uref, upump_p);
    return true;
}
Пример #16
0
/** @internal @This takes the payload of a TS packet and finds PSI sections
 * inside it.
 *
 * @param upipe description structure of the pipe
 * @param uref uref structure
 * @param upump_p reference to pump that generated the buffer
 */
static void upipe_ts_psim_input(struct upipe *upipe, struct uref *uref,
                                struct upump **upump_p)
{
    struct upipe_ts_psim *upipe_ts_psim = upipe_ts_psim_from_upipe(upipe);
    if (unlikely(ubase_check(uref_flow_get_discontinuity(uref))))
        upipe_ts_psim_flush(upipe);

    if (ubase_check(uref_block_get_start(uref))) {
        if (likely(upipe_ts_psim->acquired)) {
            /* just remove pointer_field */
            if (unlikely(!ubase_check(uref_block_resize(uref, 1, -1)))) {
                uref_free(uref);
                upipe_ts_psim_flush(upipe);
                return;
            }
        } else {
            /* jump to the start of the next section */
            uint8_t pointer_field;
            if (unlikely(!ubase_check(uref_block_extract(uref, 0, 1, &pointer_field)) ||
                         !ubase_check(uref_block_resize(uref, 1 + pointer_field, -1)))) {
                uref_free(uref);
                return;
            }
            upipe_ts_psim_sync_acquired(upipe);
        }
        uref_block_delete_start(uref);

    } else if (unlikely(upipe_ts_psim->next_uref == NULL)) {
        uref_free(uref);
        upipe_ts_psim_flush(upipe);
        return;
    }

    while (upipe_ts_psim_merge(upipe, uref, upump_p));
    uref_free(uref);
}
Пример #17
0
/** @This frees a upipe.
 *
 * @param upipe description structure of the pipe
 */
static void upipe_blksrc_free(struct upipe *upipe)
{
    struct upipe_blksrc *upipe_blksrc = upipe_blksrc_from_upipe(upipe);

    upipe_throw_dead(upipe);

    uref_free(upipe_blksrc->flow_def);
    upipe_blksrc_clean_bin_output(upipe);
    upipe_blksrc_clean_bin_input(upipe);
    upipe_blksrc_clean_blk_probe(upipe);
    upipe_blksrc_clean_src_probe(upipe);
    upipe_blksrc_clean_urefcount_real(upipe);
    upipe_blksrc_clean_urefcount(upipe);
    upipe_blksrc_free_flow(upipe);
}
Пример #18
0
/** @This sets the dictionary to set into urefs.
 *
 * @param upipe description structure of the pipe
 * @param dict dictionary to set
 * @return an error code
 */
static int _upipe_setflowdef_set_dict(struct upipe *upipe, struct uref *dict)
{
    struct upipe_setflowdef *upipe_setflowdef = upipe_setflowdef_from_upipe(upipe);
    if (upipe_setflowdef->dict != NULL)
        uref_free(upipe_setflowdef->dict);
    if (dict != NULL) {
        upipe_setflowdef->dict = uref_dup(dict);
        if (upipe_setflowdef->dict == NULL) {
            upipe_throw_fatal(upipe, UBASE_ERR_ALLOC);
            return UBASE_ERR_ALLOC;
        }
    } else
        upipe_setflowdef->dict = NULL;
    upipe_setflowdef_build_flow_def(upipe);
    return UBASE_ERR_NONE;
}
Пример #19
0
/** @internal @This sets the input flow definition.
 *
 * @param upipe description structure of the pipe
 * @param flow_def flow definition packet
 * @return an error code
 */
static int upipe_setflowdef_set_flow_def(struct upipe *upipe,
                                         struct uref *flow_def)
{
    if (flow_def == NULL)
        return UBASE_ERR_INVALID;
    struct uref *flow_def_dup;
    if ((flow_def_dup = uref_dup(flow_def)) == NULL)
        return UBASE_ERR_ALLOC;

    struct upipe_setflowdef *upipe_setflowdef =
        upipe_setflowdef_from_upipe(upipe);
    uref_free(upipe_setflowdef->flow_def_input);
    upipe_setflowdef->flow_def_input = flow_def_dup;
    upipe_setflowdef_build_flow_def(upipe);
    return UBASE_ERR_NONE;
}
Пример #20
0
/** @internal @This sets the input flow def of the m3u pipe.
 *
 * @param upipe description structure of the pipe
 * @param flow_def new input flow definition
 * @return an error code
 */
static int upipe_m3u_reader_set_flow_def(struct upipe *upipe,
                                         struct uref *flow_def)
{
    struct upipe_m3u_reader *upipe_m3u_reader =
        upipe_m3u_reader_from_upipe(upipe);

    UBASE_RETURN(uref_flow_match_def(flow_def, EXPECTED_FLOW_DEF));

    struct uref *flow_def_dup = uref_dup(flow_def);
    if (unlikely(flow_def_dup == NULL)) {
        upipe_throw_fatal(upipe, UBASE_ERR_ALLOC);
        return UBASE_ERR_ALLOC;
    }

    uref_free(upipe_m3u_reader->flow_def);
    upipe_m3u_reader->flow_def = flow_def_dup;
    return UBASE_ERR_NONE;
}
Пример #21
0
/** @internal @This frees the pipe.
 *
 * @param upipe description structure of the pipe
 */
static void upipe_hls_free(struct upipe *upipe)
{
    struct upipe_hls *upipe_hls = upipe_hls_from_upipe(upipe);

    upipe_throw_dead(upipe);

    if (upipe_hls->sub_pipe_mgr)
        upipe_mgr_release(upipe_hls->sub_pipe_mgr);
    if (upipe_hls->item)
        uref_free(upipe_hls->item);
    upipe_hls_store_flow_def(upipe, NULL);
    upipe_hls_clean_bin_output(upipe);
    upipe_hls_clean_bin_input(upipe);
    upipe_hls_clean_probe_master(upipe);
    upipe_hls_clean_probe_reader(upipe);
    upipe_hls_clean_probe_null(upipe);
    upipe_hls_clean_urefcount(upipe);
    upipe_hls_clean_urefcount_real(upipe);
    upipe_hls_free_void(upipe);
}
Пример #22
0
/** helper phony pipe */
static void test_input(struct upipe *upipe, struct uref *uref,
                       struct upump **upump_p)
{
    struct x264_test *x264_test = x264_test_from_upipe(upipe);
    uint64_t pts = 0, dts = 0;
    if (uref->udict != NULL) {
        udict_dump(uref->udict, upipe->uprobe);
    }
    if (!ubase_check(uref_clock_get_pts_prog(uref, &pts))) {
        upipe_warn(upipe, "received packet with no pts");
    }
    if (!ubase_check(uref_clock_get_dts_prog(uref, &dts))) {
        upipe_warn(upipe, "received packet with no dts");
    }
    upipe_dbg_va(upipe, "received pic %d, pts: %"PRIu64" , dts: %"PRIu64,
                 x264_test->counter, pts, dts);
    x264_test->counter++;

    uref_free(uref);
}
Пример #23
0
/** @internal @This frees a burst pipe.
 *
 * @param urefcount pointer to real urefcount structure
 */
static void upipe_burst_free(struct urefcount *urefcount)
{
    struct upipe_burst *upipe_burst =
        upipe_burst_from_urefcount_real(urefcount);
    struct upipe *upipe = upipe_burst_to_upipe(upipe_burst);

    upipe_throw_dead(upipe);

    struct uchain *uchain;
    while ((uchain = ulist_pop(&upipe_burst->urefs)))
        uref_free(uref_from_uchain(uchain));

    urefcount_clean(&upipe_burst->urefcount_real);
    ueventfd_clean(&upipe_burst->ueventfd);
    upipe_burst_clean_upump(upipe);
    upipe_burst_clean_upump_mgr(upipe);
    upipe_burst_clean_output(upipe);
    upipe_burst_clean_urefcount(upipe);
    upipe_burst_free_void(upipe);
}
Пример #24
0
/** @internal @This is called to consume frames out of the first buffered uref.
 *
 * @param upipe description structure of the pipe
 * @param frames number of frames to consume
 */
static void upipe_nacl_audio_consume(struct upipe *upipe, uint32_t frames)
{
    struct upipe_nacl_audio *upipe_nacl_audio =
        upipe_nacl_audio_from_upipe(upipe);
    struct uref *uref = upipe_nacl_audio->uref;
    assert(uref != NULL);

    size_t uref_size;
    if (ubase_check(uref_sound_size(uref, &uref_size, NULL)) &&
        uref_size <= frames) {
        upipe_nacl_audio->uref = NULL;
        uref_free(uref);
    } else {
        uref_sound_resize(uref, frames, -1);
        uint64_t pts;
        if (ubase_check(uref_clock_get_pts_sys(uref, &pts)))
            uref_clock_set_pts_sys(uref,
                    pts + frames * UCLOCK_FREQ / SAMPLE_RATE);
        /* We should also change the duration but we don't use it. */
    }
}
Пример #25
0
/** @This frees a upipe.
 *
 * @param upipe description structure of the pipe
 */
static void upipe_nacl_audio_free(struct upipe *upipe)
{
    struct upipe_nacl_audio *upipe_nacl_audio =
        upipe_nacl_audio_from_upipe(upipe);
    upipe_throw_dead(upipe);

    upipe_nacl_audio->audio_interface->StopPlayback(upipe_nacl_audio->audio);
    upipe_nacl_audio->core_interface->ReleaseResource(upipe_nacl_audio->audio);
    upipe_nacl_audio->core_interface->ReleaseResource(upipe_nacl_audio->audio_config);

    struct uref *uref;
    while ((uref = uqueue_pop(&upipe_nacl_audio->uqueue,
                              struct uref *)) != NULL)
        uref_free(uref);

    upipe_nacl_audio_clean_uclock(upipe);
    upipe_nacl_audio_clean_upump_mgr(upipe);
    upipe_nacl_audio_clean_upump(upipe);
    uqueue_clean(&upipe_nacl_audio->uqueue);
    upipe_nacl_audio_clean_urefcount(upipe);
    free(upipe_nacl_audio);
}
Пример #26
0
static void upipe_rtp_h264_input(struct upipe *upipe,
                                struct uref *uref,
                                struct upump **upump_p)
{
    size_t bz = 0;
    if (!ubase_check(uref_block_size(uref, &bz))) {
        upipe_err(upipe, "fail to get uref block size");
        return upipe_rtp_h264_drop(upipe, uref);
    }

    uint8_t buf[bz];
    int size = bz;
    if (unlikely(!ubase_check(uref_block_extract(uref, 0, size, buf)))) {
        upipe_err(upipe, "fail to read from uref");
        return upipe_rtp_h264_drop(upipe, uref);
    }

    uint8_t s_len;
    const uint8_t *s = upipe_mpeg_scan(buf, buf + size, &s_len);
    if (s != buf) {
        upipe_err(upipe, "uref does not start with a mpeg start code");
        return upipe_rtp_h264_drop(upipe, uref);
    }

    while (s < buf + size) {
        uint8_t e_len = 0;
        const uint8_t *e = upipe_mpeg_scan(s + s_len, buf + size, &e_len);
        if (!e)
            e = buf + size;

        struct uref *part = uref_block_splice(uref, s - buf + s_len + 1,
                                              e - (s + s_len + 1));
        upipe_rtp_h264_output_nalu(upipe, *(s + s_len), part, upump_p);
        s = e;
        s_len = e_len;
    }

    uref_free(uref);
}
Пример #27
0
/** @internal @This is called by avcodec when releasing a frame
 * @param context current avcodec context
 * @param frame avframe handler released by avcodec black magic box
 */
static void upipe_avcdec_release_buffer(struct AVCodecContext *context, AVFrame *frame)
{
    struct upipe *upipe = context->opaque;
    struct uref *uref = frame->opaque;
    const struct upipe_av_plane *planes = NULL;
    int i;

    uint64_t framenum = 0;
    uref_pic_get_number(uref, &framenum);

    upipe_dbg_va(upipe, "Releasing frame %u (%p)", (uint64_t) framenum, uref);

    if (likely(uref->ubuf)) {
        planes = upipe_avcdec_from_upipe(upipe)->pixfmt->planes;
        for (i=0; i < 4 && planes[i].chroma; i++) {
            ubuf_pic_plane_unmap(uref->ubuf, planes[i].chroma, 0, 0, -1, -1);
            frame->data[i] = NULL;
        }
    } else {
        avcodec_default_release_buffer(context, frame);
    }
    uref_free(uref);
}
Пример #28
0
/** @internal @This outputs the m3u.
 *
 * @param upipe description structure of the pipe
 * @param upump_p reference to source pump to block
 */
static void upipe_m3u_reader_output_all(struct upipe *upipe,
                                        struct upump **upump_p)
{
    struct upipe_m3u_reader *upipe_m3u_reader =
        upipe_m3u_reader_from_upipe(upipe);

    struct uref *flow_def = upipe_m3u_reader->current_flow_def;
    upipe_m3u_reader->current_flow_def = NULL;
    if (unlikely(!ubase_check(uref_flow_match_def(flow_def, M3U_FLOW_DEF)))) {
        upipe_err(upipe, "invalid m3u");
        uref_free(flow_def);
        return;
    }

    /* force new flow def */
    upipe_m3u_reader_store_flow_def(upipe, NULL);
    /* set output flow def */
    upipe_m3u_reader_store_flow_def(upipe, flow_def);

    /* output */
    struct uchain *uchain;
    bool first = true;
    upipe_use(upipe);
    while ((uchain = ulist_pop(&upipe_m3u_reader->items)) != NULL) {
        struct uref *uref = uref_from_uchain(uchain);

        if (first)
            uref_block_set_start(uref);
        first = false;

        if (ulist_empty(&upipe_m3u_reader->items))
            uref_block_set_end(uref);

        upipe_m3u_reader_output(upipe, uref, upump_p);
    }
    upipe_release(upipe);
}
Пример #29
0
/** @internal @This allocates and initializes a void source pipe.
 *
 * @param mgr pointer to upipe manager
 * @param uprobe structure used to raise events
 * @param signature signature of the pipe allocator
 * @param args optional arguments
 * @return an alloocated and initialized pipe or NULL
 */
static struct upipe *upipe_voidsrc_alloc(struct upipe_mgr *mgr,
                                         struct uprobe *uprobe,
                                         uint32_t signature, va_list args)
{
    struct uref *flow;
    struct upipe *upipe = upipe_voidsrc_alloc_flow(mgr, uprobe,
                                                   signature, args,
                                                   &flow);
    if (unlikely(!upipe))
        return NULL;

    uint64_t duration = 0;
    if (unlikely(!ubase_check(
        uref_clock_get_duration(flow, &duration)))) {
        uref_free(flow);
        upipe_voidsrc_free_flow(upipe);
        return NULL;
    }

    upipe_voidsrc_init_urefcount(upipe);
    upipe_voidsrc_init_output(upipe);
    upipe_voidsrc_init_uref_mgr(upipe);
    upipe_voidsrc_init_uclock(upipe);
    upipe_voidsrc_init_upump_mgr(upipe);
    upipe_voidsrc_init_timer(upipe);

    struct upipe_voidsrc *upipe_voidsrc = upipe_voidsrc_from_upipe(upipe);
    upipe_voidsrc->interval = duration;
    upipe_voidsrc->pts = UINT64_MAX;

    upipe_throw_ready(upipe);

    upipe_voidsrc_store_flow_def(upipe, flow);

    return upipe;
}
Пример #30
0
/** @internal @This works on a telx frame and outputs it.
 *
 * @param upipe description structure of the pipe
 * @param upump_p reference to pump that generated the buffer
 */
static void upipe_telxf_work(struct upipe *upipe, struct upump **upump_p)
{
    struct upipe_telxf *upipe_telxf = upipe_telxf_from_upipe(upipe);
    uint64_t octetrate =
        (upipe_telxf->next_uref_size * upipe_telxf->fps.num +
         upipe_telxf->fps.den - 1) / upipe_telxf->fps.den;
    if (octetrate != upipe_telxf->octetrate) {
        upipe_telxf->octetrate = octetrate;

        struct uref *flow_def = upipe_telxf_alloc_flow_def_attr(upipe);
        if (unlikely(flow_def == NULL)) {
            upipe_throw_fatal(upipe, UBASE_ERR_ALLOC);
            uref_free(upipe_telxf->next_uref);
            goto upipe_telxf_work_err;
        }

        UBASE_FATAL(upipe, uref_pic_flow_set_fps(flow_def, upipe_telxf->fps))
        UBASE_FATAL(upipe, uref_block_flow_set_octetrate(flow_def,
                                upipe_telxf->octetrate))

        flow_def = upipe_telxf_store_flow_def_attr(upipe, flow_def);
        if (unlikely(flow_def == NULL)) {
            upipe_throw_fatal(upipe, UBASE_ERR_ALLOC);
            uref_free(upipe_telxf->next_uref);
            goto upipe_telxf_work_err;
        }
        upipe_telxf_store_flow_def(upipe, flow_def);
    }

    upipe_telxf_sync_acquired(upipe);

    uint64_t duration = UCLOCK_FREQ * upipe_telxf->fps.den /
                        upipe_telxf->fps.num;

    /* We work on encoded data so in the DTS domain. Rebase on DTS. */
    uint64_t date;
    struct urational drift_rate;
    drift_rate.den = 0;
    uref_clock_get_rate(upipe_telxf->next_uref, &drift_rate);
#define SET_DATE(dv)                                                        \
    if (ubase_check(uref_clock_get_dts_##dv(upipe_telxf->next_uref, &date)))\
        uref_clock_set_dts_##dv(&upipe_telxf->au_uref_s, date);             \
    if (ubase_check(uref_clock_get_dts_##dv(&upipe_telxf->au_uref_s,        \
                                            &date))) {                      \
        uref_clock_set_dts_##dv(upipe_telxf->next_uref, date);              \
        uref_clock_set_dts_##dv(&upipe_telxf->au_uref_s, date + duration);  \
    } else if (ubase_check(uref_clock_get_cr_##dv(upipe_telxf->next_uref,   \
                                                  &date))) {                \
        /* EN 300 472 Annex A */                                            \
        uref_clock_set_dts_##dv(upipe_telxf->next_uref,                     \
                                date + MAX_DELAY_TELX);                     \
        uref_clock_set_dts_##dv(&upipe_telxf->au_uref_s, date +             \
                                MAX_DELAY_TELX + duration);                 \
    }
    SET_DATE(sys)
    SET_DATE(prog)
    SET_DATE(orig)
#undef SET_DATE

    uref_clock_set_dts_pts_delay(upipe_telxf->next_uref, 0);
    if (drift_rate.den)
        uref_clock_set_rate(upipe_telxf->next_uref, drift_rate);

    upipe_telxf_output(upipe, upipe_telxf->next_uref, upump_p);
upipe_telxf_work_err:
    upipe_telxf->next_uref = NULL;
    upipe_telxf->next_uref_size = 0;
}