示例#1
0
文件: cbs.c 项目: libav/libav
int ff_cbs_read_unsigned(CodedBitstreamContext *ctx, BitstreamContext *bc,
                         int width, const char *name, uint32_t *write_to,
                         uint32_t range_min, uint32_t range_max)
{
    uint32_t value;
    int position;

    av_assert0(width <= 32);

    if (bitstream_bits_left(bc) < width) {
        av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid value at "
               "%s: bitstream ended.\n", name);
        return AVERROR_INVALIDDATA;
    }

    if (ctx->trace_enable)
        position = bitstream_tell(bc);

    value = bitstream_read(bc, width);

    if (ctx->trace_enable) {
        char bits[33];
        int i;
        for (i = 0; i < width; i++)
            bits[i] = value >> (width - i - 1) & 1 ? '1' : '0';
        bits[i] = 0;

        ff_cbs_trace_syntax_element(ctx, position, name, bits, value);
    }
示例#2
0
static int cbs_read_se_golomb(CodedBitstreamContext *ctx, BitstreamContext *bc,
                              const char *name, int32_t *write_to,
                              int32_t range_min, int32_t range_max)
{
    int32_t value;
    int position, i, j;
    unsigned int k;
    uint32_t v;
    char bits[65];

    position = bitstream_tell(bc);

    for (i = 0; i < 32; i++) {
        if (bitstream_bits_left(bc) < i + 1) {
            av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid se-golomb code at "
                   "%s: bitstream ended.\n", name);
            return AVERROR_INVALIDDATA;
        }
        k = bitstream_read_bit(bc);
        bits[i] = k ? '1' : '0';
        if (k)
            break;
    }
    if (i >= 32) {
        av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid se-golomb code at "
               "%s: more than 31 zeroes.\n", name);
        return AVERROR_INVALIDDATA;
    }
    v = 1;
    for (j = 0; j < i; j++) {
        k = bitstream_read_bit(bc);
        bits[i + j + 1] = k ? '1' : '0';
        v = v << 1 | k;
    }
    bits[i + j + 1] = 0;
    if (v & 1)
        value = -(int32_t)(v / 2);
    else
        value = v / 2;

    if (ctx->trace_enable)
        ff_cbs_trace_syntax_element(ctx, position, name, bits, value);

    if (value < range_min || value > range_max) {
        av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
               "%"PRId32", but must be in [%"PRId32",%"PRId32"].\n",
               name, value, range_min, range_max);
        return AVERROR_INVALIDDATA;
    }

    *write_to = value;
    return 0;
}
示例#3
0
static int decode_frame(AVCodecContext *avctx, void *data,
                        int *got_frame_ptr, AVPacket *avpkt)
{
    BinkAudioContext *s = avctx->priv_data;
    AVFrame *frame      = data;
    BitstreamContext *bc = &s->bc;
    int ret, consumed = 0;

    if (!bitstream_bits_left(bc)) {
        uint8_t *buf;
        /* handle end-of-stream */
        if (!avpkt->size) {
            *got_frame_ptr = 0;
            return 0;
        }
        if (avpkt->size < 4) {
            av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
            return AVERROR_INVALIDDATA;
        }
        buf = av_realloc(s->packet_buffer, avpkt->size + AV_INPUT_BUFFER_PADDING_SIZE);
        if (!buf)
            return AVERROR(ENOMEM);
        s->packet_buffer = buf;
        memcpy(s->packet_buffer, avpkt->data, avpkt->size);
        bitstream_init(bc, s->packet_buffer, avpkt->size * 8);
        consumed = avpkt->size;

        /* skip reported size */
        bitstream_skip(bc, 32);
    }

    /* get output buffer */
    frame->nb_samples = s->frame_len;
    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
        return ret;
    }

    if (decode_block(s, (float **)frame->extended_data,
                     avctx->codec->id == AV_CODEC_ID_BINKAUDIO_DCT)) {
        av_log(avctx, AV_LOG_ERROR, "Incomplete packet\n");
        return AVERROR_INVALIDDATA;
    }
    get_bits_align32(bc);

    frame->nb_samples = s->block_size / avctx->channels;
    *got_frame_ptr    = 1;

    return consumed;
}
示例#4
0
static int parse_fmtp_config(AVStream *st, const char *value)
{
    int len = ff_hex_to_data(NULL, value), i, ret = 0;
    BitstreamContext bc;
    uint8_t *config;
    int audio_mux_version, same_time_framing, num_programs, num_layers;

    /* Pad this buffer, too, to avoid out of bounds reads with get_bits below */
    config = av_mallocz(len + AV_INPUT_BUFFER_PADDING_SIZE);
    if (!config)
        return AVERROR(ENOMEM);
    ff_hex_to_data(config, value);
    bitstream_init8(&bc, config, len);
    audio_mux_version = bitstream_read(&bc, 1);
    same_time_framing = bitstream_read(&bc, 1);
    bitstream_skip(&bc, 6); /* num_sub_frames */
    num_programs      = bitstream_read(&bc, 4);
    num_layers        = bitstream_read(&bc, 3);
    if (audio_mux_version != 0 || same_time_framing != 1 || num_programs != 0 ||
        num_layers != 0) {
        avpriv_report_missing_feature(NULL, "LATM config (%d,%d,%d,%d)",
                                      audio_mux_version, same_time_framing,
                                      num_programs, num_layers);
        ret = AVERROR_PATCHWELCOME;
        goto end;
    }
    av_freep(&st->codecpar->extradata);
    st->codecpar->extradata_size = (bitstream_bits_left(&bc) + 7) / 8;
    st->codecpar->extradata = av_mallocz(st->codecpar->extradata_size +
                                         AV_INPUT_BUFFER_PADDING_SIZE);
    if (!st->codecpar->extradata) {
        ret = AVERROR(ENOMEM);
        goto end;
    }
    for (i = 0; i < st->codecpar->extradata_size; i++)
        st->codecpar->extradata[i] = bitstream_read(&bc, 8);

end:
    av_free(config);
    return ret;
}
示例#5
0
/**
 * Decode Bink Audio block
 * @param[out] out Output buffer (must contain s->block_size elements)
 * @return 0 on success, negative error code on failure
 */
static int decode_block(BinkAudioContext *s, float **out, int use_dct)
{
    int ch, i, j, k;
    float q, quant[25];
    int width, coeff;
    BitstreamContext *bc = &s->bc;

    if (use_dct)
        bitstream_skip(bc, 2);

    for (ch = 0; ch < s->channels; ch++) {
        FFTSample *coeffs = out[ch];

        if (s->version_b) {
            if (bitstream_bits_left(bc) < 64)
                return AVERROR_INVALIDDATA;
            coeffs[0] = av_int2float(bitstream_read(bc, 32)) * s->root;
            coeffs[1] = av_int2float(bitstream_read(bc, 32)) * s->root;
        } else {
            if (bitstream_bits_left(bc) < 58)
                return AVERROR_INVALIDDATA;
            coeffs[0] = get_float(bc) * s->root;
            coeffs[1] = get_float(bc) * s->root;
        }

        if (bitstream_bits_left(bc) < s->num_bands * 8)
            return AVERROR_INVALIDDATA;
        for (i = 0; i < s->num_bands; i++) {
            int value = bitstream_read(bc, 8);
            quant[i]  = quant_table[FFMIN(value, 95)];
        }

        k = 0;
        q = quant[0];

        // parse coefficients
        i = 2;
        while (i < s->frame_len) {
            if (s->version_b) {
                j = i + 16;
            } else {
                int v = bitstream_read_bit(bc);
                if (v) {
                    v = bitstream_read(bc, 4);
                    j = i + rle_length_tab[v] * 8;
                } else {
                    j = i + 8;
                }
            }

            j = FFMIN(j, s->frame_len);

            width = bitstream_read(bc, 4);
            if (width == 0) {
                memset(coeffs + i, 0, (j - i) * sizeof(*coeffs));
                i = j;
                while (s->bands[k] < i)
                    q = quant[k++];
            } else {
                while (i < j) {
                    if (s->bands[k] == i)
                        q = quant[k++];
                    coeff = bitstream_read(bc, width);
                    if (coeff) {
                        int v;
                        v = bitstream_read_bit(bc);
                        if (v)
                            coeffs[i] = -q * coeff;
                        else
                            coeffs[i] =  q * coeff;
                    } else {
                        coeffs[i] = 0.0f;
                    }
                    i++;
                }
            }
        }

        if (CONFIG_BINKAUDIO_DCT_DECODER && use_dct) {
            coeffs[0] /= 0.5;
            s->trans.dct.dct_calc(&s->trans.dct,  coeffs);
        }
        else if (CONFIG_BINKAUDIO_RDFT_DECODER)
            s->trans.rdft.rdft_calc(&s->trans.rdft, coeffs);
    }

    for (ch = 0; ch < s->channels; ch++) {
        int j;
        int count = s->overlap_len * s->channels;
        if (!s->first) {
            j = ch;
            for (i = 0; i < s->overlap_len; i++, j += s->channels)
                out[ch][i] = (s->previous[ch][i] * (count - j) +
                              out[ch][i] *          j) / count;
        }
        memcpy(s->previous[ch], &out[ch][s->frame_len - s->overlap_len],
               s->overlap_len * sizeof(*s->previous[ch]));
    }

    s->first = 0;

    return 0;
}
示例#6
0
static int atrac3p_decode_frame(AVCodecContext *avctx, void *data,
                                int *got_frame_ptr, AVPacket *avpkt)
{
    ATRAC3PContext *ctx = avctx->priv_data;
    AVFrame *frame      = data;
    int i, ret, ch_unit_id, ch_block = 0, out_ch_index = 0, channels_to_process;
    float **samples_p = (float **)frame->extended_data;

    frame->nb_samples = ATRAC3P_FRAME_SAMPLES;
    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
        return ret;
    }

    if ((ret = bitstream_init8(&ctx->bc, avpkt->data, avpkt->size)) < 0)
        return ret;

    if (bitstream_read_bit(&ctx->bc)) {
        av_log(avctx, AV_LOG_ERROR, "Invalid start bit!\n");
        return AVERROR_INVALIDDATA;
    }

    while (bitstream_bits_left(&ctx->bc) >= 2 &&
           (ch_unit_id = bitstream_read(&ctx->bc, 2)) != CH_UNIT_TERMINATOR) {
        if (ch_unit_id == CH_UNIT_EXTENSION) {
            avpriv_report_missing_feature(avctx, "Channel unit extension");
            return AVERROR_PATCHWELCOME;
        }
        if (ch_block >= ctx->num_channel_blocks ||
            ctx->channel_blocks[ch_block] != ch_unit_id) {
            av_log(avctx, AV_LOG_ERROR,
                   "Frame data doesn't match channel configuration!\n");
            return AVERROR_INVALIDDATA;
        }

        ctx->ch_units[ch_block].unit_type = ch_unit_id;
        channels_to_process               = ch_unit_id + 1;

        if ((ret = ff_atrac3p_decode_channel_unit(&ctx->bc,
                                                  &ctx->ch_units[ch_block],
                                                  channels_to_process,
                                                  avctx)) < 0)
            return ret;

        decode_residual_spectrum(&ctx->ch_units[ch_block], ctx->samples,
                                 channels_to_process, avctx);
        reconstruct_frame(ctx, &ctx->ch_units[ch_block],
                          channels_to_process, avctx);

        for (i = 0; i < channels_to_process; i++)
            memcpy(samples_p[out_ch_index + i], ctx->outp_buf[i],
                   ATRAC3P_FRAME_SAMPLES * sizeof(**samples_p));

        ch_block++;
        out_ch_index += channels_to_process;
    }

    *got_frame_ptr = 1;

    return avctx->block_align;
}