Ejemplo n.º 1
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_s337_encaps_set_flow_def(struct upipe *upipe,
                                          struct uref *flow_def)
{
    if (flow_def == NULL)
        return UBASE_ERR_INVALID;

    const char *def;
    UBASE_RETURN(uref_flow_get_def(flow_def, &def))

    uint64_t rate;
    UBASE_RETURN(uref_sound_flow_get_rate(flow_def, &rate))

    if (ubase_ncmp(def, EXPECTED_FLOW_DEF))
        return UBASE_ERR_INVALID;

    struct uref *flow_def_dup = uref_dup(flow_def);
    if (flow_def_dup == NULL)
        return UBASE_ERR_ALLOC;

    uref_flow_set_def(flow_def_dup, "sound.s32.s337.a52.");
    uref_sound_flow_set_channels(flow_def_dup, 2);
    uref_sound_flow_set_sample_size(flow_def_dup, 2*4);

    if (!ubase_check(uref_sound_flow_add_plane(flow_def_dup, "lr")) ||
        !ubase_check(uref_sound_flow_set_rate(flow_def_dup, rate))) {
        uref_free(flow_def_dup);
        return UBASE_ERR_ALLOC;
    }

    upipe_s337_encaps_require_ubuf_mgr(upipe, flow_def_dup);
    return UBASE_ERR_NONE;
}
Ejemplo n.º 2
0
/** @internal @This provides a flow format suggestion.
 *
 * @param upipe description structure of the pipe
 * @param request description structure of the request
 * @return an error code
 */
static int upipe_nacl_audio_provide_flow_format(struct upipe *upipe,
                                                struct urequest *request)
{
    struct uref *flow_format = uref_dup(request->uref);
    UBASE_ALLOC_RETURN(flow_format);
    uref_sound_flow_clear_format(flow_format);
    uref_flow_set_def(flow_format, EXPECTED_FLOW_DEF);
    uref_sound_flow_set_channels(flow_format, 2);
    uref_sound_flow_set_sample_size(flow_format, 4);
    uref_sound_flow_set_planes(flow_format, 0);
    uref_sound_flow_add_plane(flow_format, "lr");
    uref_sound_flow_set_rate(flow_format, SAMPLE_RATE);
    return urequest_provide_flow_format(request, flow_format);
}
Ejemplo n.º 3
0
/** @internal @This parses A/52 header.
 *
 * @param upipe description structure of the pipe
 * @return false in case the header is inconsistent
 */
static bool upipe_a52f_parse_a52(struct upipe *upipe)
{
    struct upipe_a52f *upipe_a52f = upipe_a52f_from_upipe(upipe);
    uint8_t header[A52_SYNCINFO_SIZE + 2];
    if (unlikely(!ubase_check(uref_block_extract(upipe_a52f->next_uref, 0,
                                                 sizeof(header), header))))
        return true; /* not enough data */

    ssize_t next_frame_size = a52_get_frame_size(a52_get_fscod(header),
                                                 a52_get_frmsizecod(header));
    if (!next_frame_size)
        return false;

    if (likely(a52_sync_compare_formats(header, upipe_a52f->sync_header) &&
               header[5] == upipe_a52f->sync_header[5] &&
               header[6] == upipe_a52f->sync_header[6])) {
        /* identical sync */
        upipe_a52f->next_frame_size = next_frame_size;
        return true;
    }

    /* sample rate */
    uint64_t samplerate;
    switch (a52_get_fscod(header)) {
        case A52_FSCOD_48KHZ:
            samplerate = 48000;
            break;
        case A52_FSCOD_441KHZ:
            samplerate = 44100;
            break;
        case A52_FSCOD_32KHZ:
            samplerate = 32000;
            break;
        default:
            upipe_warn(upipe, "reserved fscod");
            return false;
    }

    /* frame size */
    upipe_a52f->next_frame_size = next_frame_size;

    /* channels */
    int acmod = a52_get_acmod(header);
    int channels = acmod_chans[acmod].nfchans +
        ((header[6] >> (4 - acmod_chans[acmod].lfe_offset)) & 1);

    uint64_t octetrate = a52_bitrate_tab[a52_get_frmsizecod(header)] * 1000 / 8;
    memcpy(upipe_a52f->sync_header, header, A52_SYNCINFO_SIZE + 2);
    upipe_a52f->samplerate = samplerate;

    struct uref *flow_def = upipe_a52f_alloc_flow_def_attr(upipe);
    if (unlikely(!flow_def)) {
        upipe_throw_fatal(upipe, UBASE_ERR_ALLOC);
        return false;
    }

    UBASE_FATAL(upipe, uref_flow_set_complete(flow_def))
    UBASE_FATAL(upipe, uref_flow_set_def(flow_def, "block.ac3.sound."))
    UBASE_FATAL(upipe, uref_sound_flow_set_samples(flow_def, A52_FRAME_SAMPLES))
    UBASE_FATAL(upipe, uref_sound_flow_set_rate(flow_def, samplerate))
    UBASE_FATAL(upipe, uref_sound_flow_set_channels(flow_def, channels))
    UBASE_FATAL(upipe, uref_clock_set_latency(flow_def,
                upipe_a52f->input_latency +
                UCLOCK_FREQ * A52_FRAME_SAMPLES / samplerate))
    UBASE_FATAL(upipe, uref_block_flow_set_octetrate(flow_def, octetrate))

    flow_def = upipe_a52f_store_flow_def_attr(upipe, flow_def);
    if (unlikely(!flow_def)) {
        upipe_throw_fatal(upipe, UBASE_ERR_ALLOC);
        return false;
    }
    upipe_a52f_store_flow_def(upipe, flow_def);

    return true;
}
Ejemplo n.º 4
0
/** @internal @This parses A/52 Annex E header.
 *
 * @param upipe description structure of the pipe
 * @return false in case the header is inconsistent
 */
static bool upipe_a52f_parse_a52e(struct upipe *upipe)
{
    struct upipe_a52f *upipe_a52f = upipe_a52f_from_upipe(upipe);
    uint8_t header[A52_SYNCINFO_SIZE];
    if (unlikely(!ubase_check(uref_block_extract(upipe_a52f->next_uref, 0,
                                                 sizeof(header), header))))
        return true; /* not enough data */

    if (likely(a52e_sync_compare_formats(header, upipe_a52f->sync_header))) {
        /* identical sync */
        upipe_a52f->next_frame_size =
            a52e_get_frame_size(a52e_get_frmsiz(header));
        return true;
    }

    /* sample rate */
    uint64_t samplerate;
    switch (a52e_get_fscod(header)) {
        case A52_FSCOD_48KHZ:
            samplerate = 48000;
            break;
        case A52_FSCOD_441KHZ:
            samplerate = 44100;
            break;
        case A52_FSCOD_32KHZ:
            samplerate = 32000;
            break;
        case A52_FSCOD_RESERVED:
            switch (a52e_get_fscod2(header)) {
                case A52E_FSCOD2_24KHZ:
                    samplerate = 24000;
                    break;
                case A52E_FSCOD2_2205KHZ:
                    samplerate = 22050;
                    break;
                case A52E_FSCOD2_16KHZ:
                    samplerate = 16000;
                    break;
                default:
                    upipe_warn(upipe, "reserved fscod2");
                    return false;
            }
            break;
        default: /* never reached */
            return false;
    }

    /* frame size */
    upipe_a52f->next_frame_size = a52e_get_frame_size(a52e_get_frmsiz(header));

    /* channels */
    int acmod = a52e_get_acmod(header);
    int channels = acmod_chans[acmod].nfchans + a52e_get_lfeon(header);

    uint64_t octetrate =
          (upipe_a52f->next_frame_size * samplerate + A52_FRAME_SAMPLES - 1) /
          A52_FRAME_SAMPLES;
    memcpy(upipe_a52f->sync_header, header, A52_SYNCINFO_SIZE);
    upipe_a52f->samplerate = samplerate;

    struct uref *flow_def = upipe_a52f_alloc_flow_def_attr(upipe);
    if (unlikely(!flow_def)) {
        upipe_throw_fatal(upipe, UBASE_ERR_ALLOC);
        return false;
    }

    UBASE_FATAL(upipe, uref_flow_set_complete(flow_def))
    UBASE_FATAL(upipe, uref_flow_set_def(flow_def, "block.eac3.sound."))
    UBASE_FATAL(upipe, uref_sound_flow_set_samples(flow_def, A52_FRAME_SAMPLES))
    UBASE_FATAL(upipe, uref_sound_flow_set_rate(flow_def, samplerate))
    UBASE_FATAL(upipe, uref_sound_flow_set_channels(flow_def, channels))
    UBASE_FATAL(upipe, uref_clock_set_latency(flow_def,
                upipe_a52f->input_latency +
                UCLOCK_FREQ * A52_FRAME_SAMPLES / samplerate))
    UBASE_FATAL(upipe, uref_block_flow_set_octetrate(flow_def, octetrate))

    flow_def = upipe_a52f_store_flow_def_attr(upipe, flow_def);
    if (unlikely(!flow_def)) {
        upipe_throw_fatal(upipe, UBASE_ERR_ALLOC);
        return false;
    }
    upipe_a52f_store_flow_def(upipe, flow_def);

    return true;
}
Ejemplo n.º 5
0
/** @internal @This outputs audio buffers
 *
 * @param upipe description structure of the pipe
 * @param frame AVFrame structure
 * @param upump upump structure
 */
static void upipe_avcdec_output_audio(struct upipe *upipe, AVFrame *frame,
                                     struct upump *upump)
{
    struct ubuf *ubuf;
    struct upipe_avcdec *upipe_avcdec = upipe_avcdec_from_upipe(upipe);
    struct uref *uref = frame->opaque;
    int bufsize = -1, avbufsize;
    size_t size = 0;
    uint8_t *buf;
    AVCodecContext *context = upipe_avcdec->context;

    /* fetch audio sample size (in case it has been reduced) */
    avbufsize = av_samples_get_buffer_size(NULL, context->channels,
                       frame->nb_samples, context->sample_fmt, 1);

    /* if uref has no attached ubuf (ie DR not supported) */
    if (unlikely(!uref->ubuf)) {
        ubuf = ubuf_block_alloc(upipe_avcdec->ubuf_mgr, avbufsize);
        if (unlikely(!ubuf)) {
            upipe_throw_aerror(upipe);
            return;
        }

        ubuf_block_write(ubuf, 0, &bufsize, &buf);
        memcpy(buf, frame->data[0], bufsize);

        uref_attach_ubuf(uref, ubuf);
    }

    /* unmap, reduce block if needed */
    uref_block_unmap(uref, 0);
    uref_block_size(uref, &size);
    if (unlikely(size != avbufsize)) {
        uref_block_resize(uref, 0, avbufsize);
    }

    /* TODO: set attributes/need a real ubuf_audio structure (?) */
    if (!upipe_avcdec->output_flow) {
        #if 0
        struct uref *outflow = uref_sound_flow_alloc_def(upipe_avcdec->uref_mgr,
                    context->channels,
                    av_get_bytes_per_sample(context->sample_fmt));
        #else

        struct uref *outflow = uref_block_flow_alloc_def(upipe_avcdec->uref_mgr,
                                                        "sound.");

        #endif
        uref_sound_flow_set_channels(outflow, context->channels);
        uref_sound_flow_set_sample_size(outflow,
                                 av_get_bytes_per_sample(context->sample_fmt));
        uref_sound_flow_set_rate(outflow, context->sample_rate);

        upipe_avcdec_store_flow_def(upipe, outflow);
    }

    /* samples in uref */
    uref_sound_flow_set_samples(uref, frame->nb_samples);

    /* index rap attribute */
    upipe_avcdec_set_index_rap(upipe, uref);

    upipe_avcdec_output(upipe, uref, upump);
}