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); }
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; }
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; }
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; }
/** * 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; }
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; }