+
+ /** decode scale factors */
+ if (decode_scale_factors(s) < 0)
+ return AVERROR_INVALIDDATA;
+ }
+
+ av_dlog(s->avctx, "BITSTREAM: subframe header length was %i\n",
+ get_bits_count(&s->gb) - s->subframe_offset);
+
+ /** parse coefficients */
+ for (i = 0; i < s->channels_for_cur_subframe; i++) {
+ int c = s->channel_indexes_for_cur_subframe[i];
+ if (s->channel[c].transmit_coefs &&
+ get_bits_count(&s->gb) < s->num_saved_bits) {
+ decode_coeffs(s, c);
+ } else
+ memset(s->channel[c].coeffs, 0,
+ sizeof(*s->channel[c].coeffs) * subframe_len);
+ }
+
+ av_dlog(s->avctx, "BITSTREAM: subframe length was %i\n",
+ get_bits_count(&s->gb) - s->subframe_offset);
+
+ if (transmit_coeffs) {
+ FFTContext *mdct = &s->mdct_ctx[av_log2(subframe_len) - WMAPRO_BLOCK_MIN_BITS];
+ /** reconstruct the per channel data */
+ inverse_channel_transform(s);
+ for (i = 0; i < s->channels_for_cur_subframe; i++) {
+ int c = s->channel_indexes_for_cur_subframe[i];
+ const int* sf = s->channel[c].scale_factors;
+ int b;
+
+ if (c == s->lfe_channel)
+ memset(&s->tmp[cur_subwoofer_cutoff], 0, sizeof(*s->tmp) *
+ (subframe_len - cur_subwoofer_cutoff));
+
+ /** inverse quantization and rescaling */
+ for (b = 0; b < s->num_bands; b++) {
+ const int end = FFMIN(s->cur_sfb_offsets[b+1], s->subframe_len);
+ const int exp = s->channel[c].quant_step -
+ (s->channel[c].max_scale_factor - *sf++) *
+ s->channel[c].scale_factor_step;
+ const float quant = pow(10.0, exp / 20.0);
+ int start = s->cur_sfb_offsets[b];
+ s->dsp.vector_fmul_scalar(s->tmp + start,
+ s->channel[c].coeffs + start,
+ quant, end - start);
+ }
+
+ /** apply imdct (imdct_half == DCTIV with reverse) */
+ mdct->imdct_half(mdct, s->channel[c].coeffs, s->tmp);
+ }
+ }
+
+ /** window and overlapp-add */
+ wmapro_window(s);
+
+ /** handled one subframe */
+ for (i = 0; i < s->channels_for_cur_subframe; i++) {
+ int c = s->channel_indexes_for_cur_subframe[i];
+ if (s->channel[c].cur_subframe >= s->channel[c].num_subframes) {
+ av_log(s->avctx, AV_LOG_ERROR, "broken subframe\n");
+ return AVERROR_INVALIDDATA;
+ }
+ ++s->channel[c].cur_subframe;
+ }
+
+ return 0;
+}
+
+/**
+ *@brief Decode one WMA frame.
+ *@param s codec context
+ *@return 0 if the trailer bit indicates that this is the last frame,
+ * 1 if there are additional frames
+ */
+static int decode_frame(WMAProDecodeCtx *s, int *got_frame_ptr)
+{
+ AVCodecContext *avctx = s->avctx;
+ GetBitContext* gb = &s->gb;
+ int more_frames = 0;
+ int len = 0;
+ int i, ret;
+ const float *out_ptr[WMAPRO_MAX_CHANNELS];
+ float *samples;
+
+ /** get frame length */
+ if (s->len_prefix)
+ len = get_bits(gb, s->log2_frame_size);
+
+ av_dlog(s->avctx, "decoding frame with length %x\n", len);
+
+ /** decode tile information */
+ if (decode_tilehdr(s)) {
+ s->packet_loss = 1;
+ return 0;
+ }
+
+ /** read postproc transform */
+ if (s->num_channels > 1 && get_bits1(gb)) {
+ if (get_bits1(gb)) {
+ for (i = 0; i < s->num_channels * s->num_channels; i++)
+ skip_bits(gb, 4);
+ }
+ }
+
+ /** read drc info */
+ if (s->dynamic_range_compression) {
+ s->drc_gain = get_bits(gb, 8);
+ av_dlog(s->avctx, "drc_gain %i\n", s->drc_gain);
+ }
+
+ /** no idea what these are for, might be the number of samples
+ that need to be skipped at the beginning or end of a stream */
+ if (get_bits1(gb)) {
+ int av_unused skip;
+
+ /** usually true for the first frame */
+ if (get_bits1(gb)) {
+ skip = get_bits(gb, av_log2(s->samples_per_frame * 2));
+ av_dlog(s->avctx, "start skip: %i\n", skip);
+ }
+
+ /** sometimes true for the last frame */
+ if (get_bits1(gb)) {
+ skip = get_bits(gb, av_log2(s->samples_per_frame * 2));
+ av_dlog(s->avctx, "end skip: %i\n", skip);
+ }
+
+ }
+
+ av_dlog(s->avctx, "BITSTREAM: frame header length was %i\n",
+ get_bits_count(gb) - s->frame_offset);
+
+ /** reset subframe states */
+ s->parsed_all_subframes = 0;
+ for (i = 0; i < s->num_channels; i++) {
+ s->channel[i].decoded_samples = 0;
+ s->channel[i].cur_subframe = 0;
+ s->channel[i].reuse_sf = 0;
+ }
+
+ /** decode all subframes */
+ while (!s->parsed_all_subframes) {
+ if (decode_subframe(s) < 0) {
+ s->packet_loss = 1;
+ return 0;
+ }
+ }
+
+ /* get output buffer */
+ s->frame.nb_samples = s->samples_per_frame;
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ s->packet_loss = 1;
+ return 0;
+ }
+ samples = (float *)s->frame.data[0];
+
+ /** interleave samples and write them to the output buffer */
+ for (i = 0; i < s->num_channels; i++)
+ out_ptr[i] = s->channel[i].out;
+ s->fmt_conv.float_interleave(samples, out_ptr, s->samples_per_frame,
+ s->num_channels);
+
+ for (i = 0; i < s->num_channels; i++) {
+ /** reuse second half of the IMDCT output for the next frame */
+ memcpy(&s->channel[i].out[0],
+ &s->channel[i].out[s->samples_per_frame],
+ s->samples_per_frame * sizeof(*s->channel[i].out) >> 1);
+ }
+
+ if (s->skip_frame) {
+ s->skip_frame = 0;
+ *got_frame_ptr = 0;
+ } else {
+ *got_frame_ptr = 1;
+ }
+
+ if (s->len_prefix) {
+ if (len != (get_bits_count(gb) - s->frame_offset) + 2) {
+ /** FIXME: not sure if this is always an error */
+ av_log(s->avctx, AV_LOG_ERROR,
+ "frame[%i] would have to skip %i bits\n", s->frame_num,
+ len - (get_bits_count(gb) - s->frame_offset) - 1);
+ s->packet_loss = 1;
+ return 0;
+ }
+
+ /** skip the rest of the frame data */
+ skip_bits_long(gb, len - (get_bits_count(gb) - s->frame_offset) - 1);
+ } else {
+ while (get_bits_count(gb) < s->num_saved_bits && get_bits1(gb) == 0) {
+ }
+ }
+
+ /** decode trailer bit */
+ more_frames = get_bits1(gb);
+
+ ++s->frame_num;
+ return more_frames;
+}
+
+/**
+ *@brief Calculate remaining input buffer length.
+ *@param s codec context
+ *@param gb bitstream reader context
+ *@return remaining size in bits
+ */
+static int remaining_bits(WMAProDecodeCtx *s, GetBitContext *gb)
+{
+ return s->buf_bit_size - get_bits_count(gb);
+}
+
+/**
+ *@brief Fill the bit reservoir with a (partial) frame.
+ *@param s codec context
+ *@param gb bitstream reader context
+ *@param len length of the partial frame
+ *@param append decides whether to reset the buffer or not
+ */
+static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len,
+ int append)
+{
+ int buflen;
+
+ /** when the frame data does not need to be concatenated, the input buffer
+ is resetted and additional bits from the previous frame are copyed
+ and skipped later so that a fast byte copy is possible */
+
+ if (!append) {
+ s->frame_offset = get_bits_count(gb) & 7;
+ s->num_saved_bits = s->frame_offset;
+ init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE);
+ }
+
+ buflen = (s->num_saved_bits + len + 8) >> 3;
+
+ if (len <= 0 || buflen > MAX_FRAMESIZE) {
+ av_log_ask_for_sample(s->avctx, "input buffer too small\n");
+ s->packet_loss = 1;
+ return;
+ }
+
+ s->num_saved_bits += len;
+ if (!append) {
+ avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3),
+ s->num_saved_bits);
+ } else {
+ int align = 8 - (get_bits_count(gb) & 7);
+ align = FFMIN(align, len);
+ put_bits(&s->pb, align, get_bits(gb, align));
+ len -= align;
+ avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), len);
+ }
+ skip_bits_long(gb, len);
+
+ {
+ PutBitContext tmp = s->pb;
+ flush_put_bits(&tmp);
+ }
+
+ init_get_bits(&s->gb, s->frame_data, s->num_saved_bits);
+ skip_bits(&s->gb, s->frame_offset);
+}
+
+/**
+ *@brief Decode a single WMA packet.
+ *@param avctx codec context
+ *@param data the output buffer
+ *@param data_size number of bytes that were written to the output buffer
+ *@param avpkt input packet
+ *@return number of bytes that were read from the input buffer
+ */
+static int decode_packet(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket* avpkt)
+{
+ WMAProDecodeCtx *s = avctx->priv_data;
+ GetBitContext* gb = &s->pgb;
+ const uint8_t* buf = avpkt->data;
+ int buf_size = avpkt->size;
+ int num_bits_prev_frame;
+ int packet_sequence_number;
+
+ *got_frame_ptr = 0;
+
+ if (s->packet_done || s->packet_loss) {
+ s->packet_done = 0;
+
+ /** sanity check for the buffer length */
+ if (buf_size < avctx->block_align)
+ return 0;
+
+ s->next_packet_start = buf_size - avctx->block_align;
+ buf_size = avctx->block_align;
+ s->buf_bit_size = buf_size << 3;
+
+ /** parse packet header */
+ init_get_bits(gb, buf, s->buf_bit_size);
+ packet_sequence_number = get_bits(gb, 4);
+ skip_bits(gb, 2);
+
+ /** get number of bits that need to be added to the previous frame */
+ num_bits_prev_frame = get_bits(gb, s->log2_frame_size);
+ av_dlog(avctx, "packet[%d]: nbpf %x\n", avctx->frame_number,
+ num_bits_prev_frame);
+
+ /** check for packet loss */
+ if (!s->packet_loss &&
+ ((s->packet_sequence_number + 1) & 0xF) != packet_sequence_number) {
+ s->packet_loss = 1;
+ av_log(avctx, AV_LOG_ERROR, "Packet loss detected! seq %x vs %x\n",
+ s->packet_sequence_number, packet_sequence_number);
+ }
+ s->packet_sequence_number = packet_sequence_number;
+
+ if (num_bits_prev_frame > 0) {
+ int remaining_packet_bits = s->buf_bit_size - get_bits_count(gb);
+ if (num_bits_prev_frame >= remaining_packet_bits) {
+ num_bits_prev_frame = remaining_packet_bits;
+ s->packet_done = 1;
+ }
+
+ /** append the previous frame data to the remaining data from the
+ previous packet to create a full frame */
+ save_bits(s, gb, num_bits_prev_frame, 1);
+ av_dlog(avctx, "accumulated %x bits of frame data\n",
+ s->num_saved_bits - s->frame_offset);
+
+ /** decode the cross packet frame if it is valid */
+ if (!s->packet_loss)
+ decode_frame(s, got_frame_ptr);
+ } else if (s->num_saved_bits - s->frame_offset) {
+ av_dlog(avctx, "ignoring %x previously saved bits\n",
+ s->num_saved_bits - s->frame_offset);
+ }
+
+ if (s->packet_loss) {
+ /** reset number of saved bits so that the decoder
+ does not start to decode incomplete frames in the
+ s->len_prefix == 0 case */
+ s->num_saved_bits = 0;
+ s->packet_loss = 0;
+ }
+
+ } else {
+ int frame_size;
+ s->buf_bit_size = (avpkt->size - s->next_packet_start) << 3;
+ init_get_bits(gb, avpkt->data, s->buf_bit_size);
+ skip_bits(gb, s->packet_offset);
+ if (s->len_prefix && remaining_bits(s, gb) > s->log2_frame_size &&
+ (frame_size = show_bits(gb, s->log2_frame_size)) &&
+ frame_size <= remaining_bits(s, gb)) {
+ save_bits(s, gb, frame_size, 0);
+ s->packet_done = !decode_frame(s, got_frame_ptr);
+ } else if (!s->len_prefix
+ && s->num_saved_bits > get_bits_count(&s->gb)) {
+ /** when the frames do not have a length prefix, we don't know
+ the compressed length of the individual frames
+ however, we know what part of a new packet belongs to the
+ previous frame
+ therefore we save the incoming packet first, then we append
+ the "previous frame" data from the next packet so that
+ we get a buffer that only contains full frames */
+ s->packet_done = !decode_frame(s, got_frame_ptr);
+ } else
+ s->packet_done = 1;