Esempio n. 1
0
static int xwd_probe(AVProbeData *p)
{
    const uint8_t *b = p->buf;
    unsigned width, bpp, bpad, lsize;

    if (   p->buf_size < XWD_HEADER_SIZE
        || AV_RB32(b     ) < XWD_HEADER_SIZE                          // header size
        || AV_RB32(b +  4) != XWD_VERSION                             // version
        || AV_RB32(b +  8) != XWD_Z_PIXMAP                            // format
        || AV_RB32(b + 12) > 32 || !AV_RB32(b + 12)                   // depth
        || AV_RB32(b + 16) == 0                                       // width
        || AV_RB32(b + 20) == 0                                       // height
        || AV_RB32(b + 28) > 1                                        // byteorder
        || AV_RB32(b + 32) & ~56 || av_popcount(AV_RB32(b + 32)) != 1 // bitmap unit
        || AV_RB32(b + 36) > 1                                        // bitorder
        || AV_RB32(b + 40) & ~56 || av_popcount(AV_RB32(b + 40)) != 1 // padding
        || AV_RB32(b + 44) > 32 || !AV_RB32(b + 44)                   // bpp
        || AV_RB32(b + 68) > 256)                                     // colours
        return 0;

    width = AV_RB32(b + 16);
    bpad  = AV_RB32(b + 40);
    bpp   = AV_RB32(b + 44);
    lsize = AV_RB32(b + 48);
    if (lsize < FFALIGN(width * bpp, bpad) >> 3)
        return 0;

    return AVPROBE_SCORE_MAX / 2 + 1;
}
Esempio n. 2
0
int CMixer::Mixing(float* pOutput, int out_samples, BYTE* pInput, int in_samples)
{
    int in_ch  = av_popcount(m_in_layout);
    int out_ch = av_popcount(m_out_layout);

    float* buf  = NULL;
    if (m_in_avsf != m_in_avsf_used) { // need convert
        buf = new float[in_samples * in_ch];
        convert_to_float(m_in_avsf, (WORD)in_ch, in_samples, pInput, buf); // convert to float
        pInput = (BYTE*)buf;
    }

    // int in_plane_size  = in_samples * (av_sample_fmt_is_planar(in_avsf) ? 1 : in_ch) * av_get_bytes_per_sample(in_avsf);
    int in_plane_size  = in_samples * in_ch * av_get_bytes_per_sample(m_in_avsf_used);
    int out_plane_size = out_samples * out_ch * sizeof(float);

    out_samples = avresample_convert(m_pAVRCxt, (uint8_t**)&pOutput, in_plane_size, out_samples, (uint8_t**)&pInput, out_plane_size, in_samples);
    if (buf) {
        delete [] buf;
    }
    if (out_samples < 0) {
        TRACE(_T("Mixer: avresample_convert failed\n"));
        return 0;
    }

    return out_samples;
}
Esempio n. 3
0
/**
 * Return the number of channels in an ExSS speaker mask (HD)
 */
static int dca_exss_mask2count(int mask)
{
    /* count bits that mean speaker pairs twice */
    return av_popcount(mask) +
           av_popcount(mask & (DCA_EXSS_CENTER_LEFT_RIGHT      |
                               DCA_EXSS_FRONT_LEFT_RIGHT       |
                               DCA_EXSS_FRONT_HIGH_LEFT_RIGHT  |
                               DCA_EXSS_WIDE_LEFT_RIGHT        |
                               DCA_EXSS_SIDE_LEFT_RIGHT        |
                               DCA_EXSS_SIDE_HIGH_LEFT_RIGHT   |
                               DCA_EXSS_SIDE_REAR_LEFT_RIGHT   |
                               DCA_EXSS_REAR_LEFT_RIGHT        |
                               DCA_EXSS_REAR_HIGH_LEFT_RIGHT));
}
Esempio n. 4
0
void ff_dca_downmix_to_stereo_fixed(DCADSPContext *dcadsp, int32_t **samples,
                                    int *coeff_l, int nsamples, int ch_mask)
{
    int pos, spkr, max_spkr = av_log2(ch_mask);
    int *coeff_r = coeff_l + av_popcount(ch_mask);

    av_assert0(DCA_HAS_STEREO(ch_mask));

    // Scale left and right channels
    pos = (ch_mask & DCA_SPEAKER_MASK_C);
    dcadsp->dmix_scale(samples[DCA_SPEAKER_L], coeff_l[pos    ], nsamples);
    dcadsp->dmix_scale(samples[DCA_SPEAKER_R], coeff_r[pos + 1], nsamples);

    // Downmix remaining channels
    for (spkr = 0; spkr <= max_spkr; spkr++) {
        if (!(ch_mask & (1U << spkr)))
            continue;

        if (*coeff_l && spkr != DCA_SPEAKER_L)
            dcadsp->dmix_add(samples[DCA_SPEAKER_L], samples[spkr],
                             *coeff_l, nsamples);

        if (*coeff_r && spkr != DCA_SPEAKER_R)
            dcadsp->dmix_add(samples[DCA_SPEAKER_R], samples[spkr],
                             *coeff_r, nsamples);

        coeff_l++;
        coeff_r++;
    }
}
Esempio n. 5
0
void ff_dca_downmix_to_stereo_float(AVFloatDSPContext *fdsp, float **samples,
                                    int *coeff_l, int nsamples, int ch_mask)
{
    int pos, spkr, max_spkr = av_log2(ch_mask);
    int *coeff_r = coeff_l + av_popcount(ch_mask);
    const float scale = 1.0f / (1 << 15);

    av_assert0(DCA_HAS_STEREO(ch_mask));

    // Scale left and right channels
    pos = (ch_mask & DCA_SPEAKER_MASK_C);
    fdsp->vector_fmul_scalar(samples[DCA_SPEAKER_L], samples[DCA_SPEAKER_L],
                             coeff_l[pos    ] * scale, nsamples);
    fdsp->vector_fmul_scalar(samples[DCA_SPEAKER_R], samples[DCA_SPEAKER_R],
                             coeff_r[pos + 1] * scale, nsamples);

    // Downmix remaining channels
    for (spkr = 0; spkr <= max_spkr; spkr++) {
        if (!(ch_mask & (1U << spkr)))
            continue;

        if (*coeff_l && spkr != DCA_SPEAKER_L)
            fdsp->vector_fmac_scalar(samples[DCA_SPEAKER_L], samples[spkr],
                                     *coeff_l * scale, nsamples);

        if (*coeff_r && spkr != DCA_SPEAKER_R)
            fdsp->vector_fmac_scalar(samples[DCA_SPEAKER_R], samples[spkr],
                                     *coeff_r * scale, nsamples);

        coeff_l++;
        coeff_r++;
    }
}
Esempio n. 6
0
DWORD CAC3Encoder::SelectLayout(DWORD layout)
{
	// check supported layouts
	if (m_pAVCodec && m_pAVCodec->channel_layouts) {
		for (size_t i = 0; m_pAVCodec->channel_layouts[i] != 0; i++) {
			if (layout == (DWORD)m_pAVCodec->channel_layouts[i]) {
				return layout;
			}
		}
	}

	// select the suitable format
	int channels = av_popcount(layout & ~AV_CH_LOW_FREQUENCY); // number of channels without lfe
	DWORD new_layout = layout & AV_CH_LOW_FREQUENCY;
	if (channels >= 5) {
		new_layout |= AV_CH_LAYOUT_5POINT0;
	} else if (channels == 4) {
		new_layout |= AV_CH_LAYOUT_QUAD;
	} else if (channels == 3) {
		new_layout |= AV_CH_LAYOUT_2_1;
	} else if (channels == 2) {
		new_layout |= AV_CH_LAYOUT_STEREO;
	} else if (channels == 1) {
		new_layout |= AV_CH_LAYOUT_MONO;
	}

	return new_layout;
}
Esempio n. 7
0
/**
 * Skip mixing coefficients of a single mix out configuration (HD)
 */
static void dca_exss_skip_mix_coeffs(GetBitContext *gb, int channels, int out_ch)
{
    int i;

    for (i = 0; i < channels; i++) {
        int mix_map_mask = get_bits(gb, out_ch);
        int num_coeffs = av_popcount(mix_map_mask);
        skip_bits_long(gb, num_coeffs * 6);
    }
}
Esempio n. 8
0
int CMixer::Mixing(float* pOutput, int out_samples, BYTE* pInput, int in_samples)
{
    int in_ch  = av_popcount(m_in_layout);
    int out_ch = av_popcount(m_out_layout);

    int in_plane_nb   = av_sample_fmt_is_planar(m_in_avsf) ? in_ch : 1;
    int in_plane_size = in_samples * (av_sample_fmt_is_planar(m_in_avsf) ? 1 : in_ch) * av_get_bytes_per_sample(m_in_avsf);
    static BYTE* ppInput[AVRESAMPLE_MAX_CHANNELS];
    for (int i = 0; i < in_plane_nb; i++) {
        ppInput[i] = pInput + i * in_plane_size;
    }

    int out_plane_size = out_samples * out_ch * sizeof(float);

    out_samples = avresample_convert(m_pAVRCxt, (uint8_t**)&pOutput, out_plane_size, out_samples, ppInput, in_plane_size, in_samples);
    if (out_samples < 0) {
        TRACE(_T("Mixer: avresample_convert failed\n"));
        return 0;
    }

    return out_samples;
}
Esempio n. 9
0
bool CAC3Encoder::Init(int sample_rate, DWORD channel_layout)
{
	StreamFinish();
	int ret;

	m_pAVCtx = avcodec_alloc_context3(m_pAVCodec);

	m_pAVCtx->bit_rate       = 640000;
	m_pAVCtx->sample_fmt     = AV_SAMPLE_FMT_FLTP;
	m_pAVCtx->sample_rate    = SelectSamplerate(sample_rate);
	m_pAVCtx->channel_layout = channel_layout;
	m_pAVCtx->channels       = av_popcount(channel_layout);

	ret = avcodec_open2(m_pAVCtx, m_pAVCodec, NULL);
	if (ret < 0) {
		DbgLog((LOG_TRACE, 3, L"CAC3Encoder::Init() : avcodec_open2() failed"));
		return false;
	}

	m_pFrame = av_frame_alloc();
	if (!m_pFrame) {
		DbgLog((LOG_TRACE, 3, L"CAC3Encoder::Init() : avcodec_alloc_frame() failed"));
		return false;
	}
	m_pFrame->nb_samples     = m_pAVCtx->frame_size;
	m_pFrame->format         = m_pAVCtx->sample_fmt;
	m_pFrame->channel_layout = m_pAVCtx->channel_layout;

	// the codec gives us the frame size, in samples,
	// we calculate the size of the samples buffer in bytes
	m_framesize  = m_pAVCtx->frame_size * m_pAVCtx->channels * sizeof(float);
	m_buffersize = av_samples_get_buffer_size(NULL, m_pAVCtx->channels, m_pAVCtx->frame_size, m_pAVCtx->sample_fmt, 0);

	m_pSamples = (float*)av_malloc(m_buffersize);
	if (!m_pSamples) {
		DbgLog((LOG_TRACE, 3, L"CAC3Encoder::Init() : av_malloc(%d) failed", m_buffersize));
		return false;
	}
	/* setup the data pointers in the AVFrame */
	ret = avcodec_fill_audio_frame(m_pFrame, m_pAVCtx->channels, m_pAVCtx->sample_fmt, (const uint8_t*)m_pSamples, m_buffersize, 0);
	if (ret < 0) {
		DbgLog((LOG_TRACE, 3, L"CAC3Encoder::Init() : avcodec_fill_audio_frame() failed"));
		return false;
	}

	return true;
}
Esempio n. 10
0
static int pcx_probe(AVProbeData *p)
{
    const uint8_t *b = p->buf;

    if (   p->buf_size < 128
        || b[0] != 10
        || b[1] > 5
        || b[2] > 1
        || av_popcount(b[3]) != 1 || b[3] > 8
        || AV_RL16(&b[4]) > AV_RL16(&b[8])
        || AV_RL16(&b[6]) > AV_RL16(&b[10])
        || b[64])
        return 0;
    b += 73;
    while (++b < p->buf + 128)
        if (*b)
            return AVPROBE_SCORE_EXTENSION / 4;

    return AVPROBE_SCORE_EXTENSION + 1;
}
Esempio n. 11
0
static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data,
                                 int *got_frame_ptr, AVPacket *avpkt)
{
    AVFrame *frame     = data;
    const uint8_t *buf = avpkt->data;
    const uint8_t *buf_end;
    int buf_size = avpkt->size;
    VmdAudioContext *s = avctx->priv_data;
    int block_type, silent_chunks, audio_chunks;
    int ret;
    uint8_t *output_samples_u8;
    int16_t *output_samples_s16;

    if (buf_size < 16) {
        av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n");
        *got_frame_ptr = 0;
        return buf_size;
    }

    block_type = buf[6];
    if (block_type < BLOCK_TYPE_AUDIO || block_type > BLOCK_TYPE_SILENCE) {
        av_log(avctx, AV_LOG_ERROR, "unknown block type: %d\n", block_type);
        return AVERROR(EINVAL);
    }
    buf      += 16;
    buf_size -= 16;

    /* get number of silent chunks */
    silent_chunks = 0;
    if (block_type == BLOCK_TYPE_INITIAL) {
        uint32_t flags;
        if (buf_size < 4) {
            av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
            return AVERROR(EINVAL);
        }
        flags         = AV_RB32(buf);
        silent_chunks = av_popcount(flags);
        buf      += 4;
        buf_size -= 4;
    } else if (block_type == BLOCK_TYPE_SILENCE) {
        silent_chunks = 1;
        buf_size = 0; // should already be zero but set it just to be sure
    }

    /* ensure output buffer is large enough */
    audio_chunks = buf_size / s->chunk_size;

    /* drop incomplete chunks */
    buf_size     = audio_chunks * s->chunk_size;

    /* get output buffer */
    frame->nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) /
                        avctx->channels;
    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
        return ret;
    output_samples_u8  =            frame->data[0];
    output_samples_s16 = (int16_t *)frame->data[0];

    /* decode silent chunks */
    if (silent_chunks > 0) {
        int silent_size = avctx->block_align * silent_chunks;
        av_assert0(avctx->block_align * silent_chunks <= frame->nb_samples * avctx->channels);

        if (s->out_bps == 2) {
            memset(output_samples_s16, 0x00, silent_size * 2);
            output_samples_s16 += silent_size;
        } else {
            memset(output_samples_u8,  0x80, silent_size);
            output_samples_u8 += silent_size;
        }
    }

    /* decode audio chunks */
    if (audio_chunks > 0) {
        buf_end = buf + buf_size;
        av_assert0((buf_size & (avctx->channels > 1)) == 0);
        while (buf_end - buf >= s->chunk_size) {
            if (s->out_bps == 2) {
                decode_audio_s16(output_samples_s16, buf, s->chunk_size,
                                 avctx->channels);
                output_samples_s16 += avctx->block_align;
            } else {
                memcpy(output_samples_u8, buf, s->chunk_size);
                output_samples_u8  += avctx->block_align;
            }
            buf += s->chunk_size;
        }
    }

    *got_frame_ptr = 1;

    return avpkt->size;
}
Esempio n. 12
0
static int parse_descriptor(DCAExssParser *s, DCAExssAsset *asset)
{
    int i, j, drc_present, descr_size, descr_pos = get_bits_count(&s->gb);

    // Size of audio asset descriptor in bytes
    descr_size = get_bits(&s->gb, 9) + 1;

    // Audio asset identifier
    asset->asset_index = get_bits(&s->gb, 3);

    //
    // Per stream static metadata
    //

    if (s->static_fields_present) {
        // Asset type descriptor presence
        if (get_bits1(&s->gb))
            // Asset type descriptor
            skip_bits(&s->gb, 4);

        // Language descriptor presence
        if (get_bits1(&s->gb))
            // Language descriptor
            skip_bits(&s->gb, 24);

        // Additional textual information presence
        if (get_bits1(&s->gb)) {
            // Byte size of additional text info
            int text_size = get_bits(&s->gb, 10) + 1;

            // Sanity check available size
            if (get_bits_left(&s->gb) < text_size * 8)
                return AVERROR_INVALIDDATA;

            // Additional textual information string
            skip_bits_long(&s->gb, text_size * 8);
        }

        // PCM bit resolution
        asset->pcm_bit_res = get_bits(&s->gb, 5) + 1;

        // Maximum sample rate
        asset->max_sample_rate = ff_dca_sampling_freqs[get_bits(&s->gb, 4)];

        // Total number of channels
        asset->nchannels_total = get_bits(&s->gb, 8) + 1;

        // One to one map channel to speakers
        if (asset->one_to_one_map_ch_to_spkr = get_bits1(&s->gb)) {
            int spkr_mask_nbits = 0;
            int spkr_remap_nsets;
            int nspeakers[8];

            // Embedded stereo flag
            asset->embedded_stereo = asset->nchannels_total > 2 && get_bits1(&s->gb);

            // Embedded 6 channels flag
            asset->embedded_6ch = asset->nchannels_total > 6 && get_bits1(&s->gb);

            // Speaker mask enabled flag
            if (asset->spkr_mask_enabled = get_bits1(&s->gb)) {
                // Number of bits for speaker activity mask
                spkr_mask_nbits = (get_bits(&s->gb, 2) + 1) << 2;

                // Loudspeaker activity mask
                asset->spkr_mask = get_bits(&s->gb, spkr_mask_nbits);
            }

            // Number of speaker remapping sets
            if ((spkr_remap_nsets = get_bits(&s->gb, 3)) && !spkr_mask_nbits) {
                av_log(s->avctx, AV_LOG_ERROR, "Speaker mask disabled yet there are remapping sets\n");
                return AVERROR_INVALIDDATA;
            }

            // Standard loudspeaker layout mask
            for (i = 0; i < spkr_remap_nsets; i++)
                nspeakers[i] = ff_dca_count_chs_for_mask(get_bits(&s->gb, spkr_mask_nbits));

            for (i = 0; i < spkr_remap_nsets; i++) {
                // Number of channels to be decoded for speaker remapping
                int nch_for_remaps = get_bits(&s->gb, 5) + 1;

                for (j = 0; j < nspeakers[i]; j++) {
                    // Decoded channels to output speaker mapping mask
                    int remap_ch_mask = get_bits_long(&s->gb, nch_for_remaps);

                    // Loudspeaker remapping codes
                    skip_bits_long(&s->gb, av_popcount(remap_ch_mask) * 5);
                }
            }
        } else {
            asset->embedded_stereo = 0;
            asset->embedded_6ch = 0;
            asset->spkr_mask_enabled = 0;
            asset->spkr_mask = 0;

            // Representation type
            asset->representation_type = get_bits(&s->gb, 3);
        }
    }

    //
    // DRC, DNC and mixing metadata
    //

    // Dynamic range coefficient presence flag
    drc_present = get_bits1(&s->gb);

    // Code for dynamic range coefficient
    if (drc_present)
        skip_bits(&s->gb, 8);

    // Dialog normalization presence flag
    if (get_bits1(&s->gb))
        // Dialog normalization code
        skip_bits(&s->gb, 5);

    // DRC for stereo downmix
    if (drc_present && asset->embedded_stereo)
        skip_bits(&s->gb, 8);

    // Mixing metadata presence flag
    if (s->mix_metadata_enabled && get_bits1(&s->gb)) {
        int nchannels_dmix;

        // External mixing flag
        skip_bits1(&s->gb);

        // Post mixing / replacement gain adjustment
        skip_bits(&s->gb, 6);

        // DRC prior to mixing
        if (get_bits(&s->gb, 2) == 3)
            // Custom code for mixing DRC
            skip_bits(&s->gb, 8);
        else
            // Limit for mixing DRC
            skip_bits(&s->gb, 3);

        // Scaling type for channels of main audio
        // Scaling parameters of main audio
        if (get_bits1(&s->gb))
            for (i = 0; i < s->nmixoutconfigs; i++)
                skip_bits_long(&s->gb, 6 * s->nmixoutchs[i]);
        else
            skip_bits_long(&s->gb, 6 * s->nmixoutconfigs);

        nchannels_dmix = asset->nchannels_total;
        if (asset->embedded_6ch)
            nchannels_dmix += 6;
        if (asset->embedded_stereo)
            nchannels_dmix += 2;

        for (i = 0; i < s->nmixoutconfigs; i++) {
            if (!s->nmixoutchs[i]) {
                av_log(s->avctx, AV_LOG_ERROR, "Invalid speaker layout mask for mixing configuration\n");
                return AVERROR_INVALIDDATA;
            }
            for (j = 0; j < nchannels_dmix; j++) {
                // Mix output mask
                int mix_map_mask = get_bits(&s->gb, s->nmixoutchs[i]);

                // Mixing coefficients
                skip_bits_long(&s->gb, av_popcount(mix_map_mask) * 6);
            }
        }
    }

    //
    // Decoder navigation data
    //

    // Coding mode for the asset
    asset->coding_mode = get_bits(&s->gb, 2);

    // Coding components used in asset
    switch (asset->coding_mode) {
    case 0: // Coding mode that may contain multiple coding components
        asset->extension_mask = get_bits(&s->gb, 12);

        if (asset->extension_mask & DCA_EXSS_CORE) {
            // Size of core component in extension substream
            asset->core_size = get_bits(&s->gb, 14) + 1;
            // Core sync word present flag
            if (get_bits1(&s->gb))
                // Core sync distance
                skip_bits(&s->gb, 2);
        }

        if (asset->extension_mask & DCA_EXSS_XBR)
            // Size of XBR extension in extension substream
            asset->xbr_size = get_bits(&s->gb, 14) + 1;

        if (asset->extension_mask & DCA_EXSS_XXCH)
            // Size of XXCH extension in extension substream
            asset->xxch_size = get_bits(&s->gb, 14) + 1;

        if (asset->extension_mask & DCA_EXSS_X96)
            // Size of X96 extension in extension substream
            asset->x96_size = get_bits(&s->gb, 12) + 1;

        if (asset->extension_mask & DCA_EXSS_LBR)
            parse_lbr_parameters(s, asset);

        if (asset->extension_mask & DCA_EXSS_XLL)
            parse_xll_parameters(s, asset);

        if (asset->extension_mask & DCA_EXSS_RSV1)
            skip_bits(&s->gb, 16);

        if (asset->extension_mask & DCA_EXSS_RSV2)
            skip_bits(&s->gb, 16);
        break;

    case 1: // Loss-less coding mode without CBR component
        asset->extension_mask = DCA_EXSS_XLL;
        parse_xll_parameters(s, asset);
        break;

    case 2: // Low bit rate mode
        asset->extension_mask = DCA_EXSS_LBR;
        parse_lbr_parameters(s, asset);
        break;

    case 3: // Auxiliary coding mode
        asset->extension_mask = 0;

        // Size of auxiliary coded data
        skip_bits(&s->gb, 14);

        // Auxiliary codec identification
        skip_bits(&s->gb, 8);

        // Aux sync word present flag
        if (get_bits1(&s->gb))
            // Aux sync distance
            skip_bits(&s->gb, 3);
        break;
    }

    if (asset->extension_mask & DCA_EXSS_XLL)
        // DTS-HD stream ID
        asset->hd_stream_id = get_bits(&s->gb, 3);

    // One to one mixing flag
    // Per channel main audio scaling flag
    // Main audio scaling codes
    // Decode asset in secondary decoder flag
    // Revision 2 DRC metadata
    // Reserved
    // Zero pad
    if (ff_dca_seek_bits(&s->gb, descr_pos + descr_size * 8)) {
        av_log(s->avctx, AV_LOG_ERROR, "Read past end of EXSS asset descriptor\n");
        return AVERROR_INVALIDDATA;
    }

    return 0;
}
Esempio n. 13
0
int ff_dca_exss_parse(DCAExssParser *s, uint8_t *data, int size)
{
    int i, ret, offset, wide_hdr, header_size;

    if ((ret = init_get_bits8(&s->gb, data, size)) < 0)
        return ret;

    // Extension substream sync word
    skip_bits_long(&s->gb, 32);

    // User defined bits
    skip_bits(&s->gb, 8);

    // Extension substream index
    s->exss_index = get_bits(&s->gb, 2);

    // Flag indicating short or long header size
    wide_hdr = get_bits1(&s->gb);

    // Extension substream header length
    header_size = get_bits(&s->gb, 8 + 4 * wide_hdr) + 1;

    // Check CRC
    if (ff_dca_check_crc(s->avctx, &s->gb, 32 + 8, header_size * 8)) {
        av_log(s->avctx, AV_LOG_ERROR, "Invalid EXSS header checksum\n");
        return AVERROR_INVALIDDATA;
    }

    s->exss_size_nbits = 16 + 4 * wide_hdr;

    // Number of bytes of extension substream
    s->exss_size = get_bits(&s->gb, s->exss_size_nbits) + 1;
    if (s->exss_size > size) {
        av_log(s->avctx, AV_LOG_ERROR, "Packet too short for EXSS frame\n");
        return AVERROR_INVALIDDATA;
    }

    // Per stream static fields presence flag
    if (s->static_fields_present = get_bits1(&s->gb)) {
        int active_exss_mask[8];

        // Reference clock code
        skip_bits(&s->gb, 2);

        // Extension substream frame duration
        skip_bits(&s->gb, 3);

        // Timecode presence flag
        if (get_bits1(&s->gb))
            // Timecode data
            skip_bits_long(&s->gb, 36);

        // Number of defined audio presentations
        s->npresents = get_bits(&s->gb, 3) + 1;
        if (s->npresents > 1) {
            avpriv_request_sample(s->avctx, "%d audio presentations", s->npresents);
            return AVERROR_PATCHWELCOME;
        }

        // Number of audio assets in extension substream
        s->nassets = get_bits(&s->gb, 3) + 1;
        if (s->nassets > 1) {
            avpriv_request_sample(s->avctx, "%d audio assets", s->nassets);
            return AVERROR_PATCHWELCOME;
        }

        // Active extension substream mask for audio presentation
        for (i = 0; i < s->npresents; i++)
            active_exss_mask[i] = get_bits(&s->gb, s->exss_index + 1);

        // Active audio asset mask
        for (i = 0; i < s->npresents; i++)
            skip_bits_long(&s->gb, av_popcount(active_exss_mask[i]) * 8);

        // Mixing metadata enable flag
        if (s->mix_metadata_enabled = get_bits1(&s->gb)) {
            int spkr_mask_nbits;

            // Mixing metadata adjustment level
            skip_bits(&s->gb, 2);

            // Number of bits for mixer output speaker activity mask
            spkr_mask_nbits = (get_bits(&s->gb, 2) + 1) << 2;

            // Number of mixing configurations
            s->nmixoutconfigs = get_bits(&s->gb, 2) + 1;

            // Speaker layout mask for mixer output channels
            for (i = 0; i < s->nmixoutconfigs; i++)
                s->nmixoutchs[i] = ff_dca_count_chs_for_mask(get_bits(&s->gb, spkr_mask_nbits));
        }
    } else {
        s->npresents = 1;
        s->nassets = 1;
    }

    // Size of encoded asset data in bytes
    offset = header_size;
    for (i = 0; i < s->nassets; i++) {
        s->assets[i].asset_offset = offset;
        s->assets[i].asset_size = get_bits(&s->gb, s->exss_size_nbits) + 1;
        offset += s->assets[i].asset_size;
        if (offset > s->exss_size) {
            av_log(s->avctx, AV_LOG_ERROR, "EXSS asset out of bounds\n");
            return AVERROR_INVALIDDATA;
        }
    }

    // Audio asset descriptor
    for (i = 0; i < s->nassets; i++) {
        if ((ret = parse_descriptor(s, &s->assets[i])) < 0)
            return ret;
        if ((ret = set_exss_offsets(&s->assets[i])) < 0) {
            av_log(s->avctx, AV_LOG_ERROR, "Invalid extension size in EXSS asset descriptor\n");
            return ret;
        }
    }

    // Backward compatible core present
    // Backward compatible core substream index
    // Backward compatible core asset index
    // Reserved
    // Byte align
    // CRC16 of extension substream header
    if (ff_dca_seek_bits(&s->gb, header_size * 8)) {
        av_log(s->avctx, AV_LOG_ERROR, "Read past end of EXSS header\n");
        return AVERROR_INVALIDDATA;
    }

    return 0;
}
Esempio n. 14
0
/**
 * Parse extension substream asset header (HD)
 */
static int dca_exss_parse_asset_header(DCAContext *s)
{
    int header_pos = get_bits_count(&s->gb);
    int header_size;
    int channels = 0;
    int embedded_stereo = 0;
    int embedded_6ch    = 0;
    int drc_code_present;
    int extensions_mask = 0;
    int i, j;

    if (get_bits_left(&s->gb) < 16)
        return AVERROR_INVALIDDATA;

    /* We will parse just enough to get to the extensions bitmask with which
     * we can set the profile value. */

    header_size = get_bits(&s->gb, 9) + 1;
    skip_bits(&s->gb, 3); // asset index

    if (s->static_fields) {
        if (get_bits1(&s->gb))
            skip_bits(&s->gb, 4); // asset type descriptor
        if (get_bits1(&s->gb))
            skip_bits_long(&s->gb, 24); // language descriptor

        if (get_bits1(&s->gb)) {
            /* How can one fit 1024 bytes of text here if the maximum value
             * for the asset header size field above was 512 bytes? */
            int text_length = get_bits(&s->gb, 10) + 1;
            if (get_bits_left(&s->gb) < text_length * 8)
                return AVERROR_INVALIDDATA;
            skip_bits_long(&s->gb, text_length * 8); // info text
        }

        skip_bits(&s->gb, 5); // bit resolution - 1
        skip_bits(&s->gb, 4); // max sample rate code
        channels = get_bits(&s->gb, 8) + 1;

        if (get_bits1(&s->gb)) { // 1-to-1 channels to speakers
            int spkr_remap_sets;
            int spkr_mask_size = 16;
            int num_spkrs[7];

            if (channels > 2)
                embedded_stereo = get_bits1(&s->gb);
            if (channels > 6)
                embedded_6ch = get_bits1(&s->gb);

            if (get_bits1(&s->gb)) {
                spkr_mask_size = (get_bits(&s->gb, 2) + 1) << 2;
                skip_bits(&s->gb, spkr_mask_size); // spkr activity mask
            }

            spkr_remap_sets = get_bits(&s->gb, 3);

            for (i = 0; i < spkr_remap_sets; i++) {
                /* std layout mask for each remap set */
                num_spkrs[i] = dca_exss_mask2count(get_bits(&s->gb, spkr_mask_size));
            }

            for (i = 0; i < spkr_remap_sets; i++) {
                int num_dec_ch_remaps = get_bits(&s->gb, 5) + 1;
                if (get_bits_left(&s->gb) < 0)
                    return AVERROR_INVALIDDATA;

                for (j = 0; j < num_spkrs[i]; j++) {
                    int remap_dec_ch_mask = get_bits_long(&s->gb, num_dec_ch_remaps);
                    int num_dec_ch = av_popcount(remap_dec_ch_mask);
                    skip_bits_long(&s->gb, num_dec_ch * 5); // remap codes
                }
            }
        } else {
            skip_bits(&s->gb, 3); // representation type
        }
    }

    drc_code_present = get_bits1(&s->gb);
    if (drc_code_present)
        get_bits(&s->gb, 8); // drc code

    if (get_bits1(&s->gb))
        skip_bits(&s->gb, 5); // dialog normalization code

    if (drc_code_present && embedded_stereo)
        get_bits(&s->gb, 8); // drc stereo code

    if (s->mix_metadata && get_bits1(&s->gb)) {
        skip_bits(&s->gb, 1); // external mix
        skip_bits(&s->gb, 6); // post mix gain code

        if (get_bits(&s->gb, 2) != 3) // mixer drc code
            skip_bits(&s->gb, 3); // drc limit
        else
            skip_bits(&s->gb, 8); // custom drc code

        if (get_bits1(&s->gb)) // channel specific scaling
            for (i = 0; i < s->num_mix_configs; i++)
                skip_bits_long(&s->gb, s->mix_config_num_ch[i] * 6); // scale codes
        else
            skip_bits_long(&s->gb, s->num_mix_configs * 6); // scale codes

        for (i = 0; i < s->num_mix_configs; i++) {
            if (get_bits_left(&s->gb) < 0)
                return AVERROR_INVALIDDATA;
            dca_exss_skip_mix_coeffs(&s->gb, channels, s->mix_config_num_ch[i]);
            if (embedded_6ch)
                dca_exss_skip_mix_coeffs(&s->gb, 6, s->mix_config_num_ch[i]);
            if (embedded_stereo)
                dca_exss_skip_mix_coeffs(&s->gb, 2, s->mix_config_num_ch[i]);
        }
    }

    switch (get_bits(&s->gb, 2)) {
    case 0:
        extensions_mask = get_bits(&s->gb, 12);
        break;
    case 1:
        extensions_mask = DCA_EXT_EXSS_XLL;
        break;
    case 2:
        extensions_mask = DCA_EXT_EXSS_LBR;
        break;
    case 3:
        extensions_mask = 0; /* aux coding */
        break;
    }

    /* not parsed further, we were only interested in the extensions mask */

    if (get_bits_left(&s->gb) < 0)
        return AVERROR_INVALIDDATA;

    if (get_bits_count(&s->gb) - header_pos > header_size * 8) {
        av_log(s->avctx, AV_LOG_WARNING, "Asset header size mismatch.\n");
        return AVERROR_INVALIDDATA;
    }
    skip_bits_long(&s->gb, header_pos + header_size * 8 - get_bits_count(&s->gb));

    if (extensions_mask & DCA_EXT_EXSS_XLL)
        s->profile = FF_PROFILE_DTS_HD_MA;
    else if (extensions_mask & (DCA_EXT_EXSS_XBR | DCA_EXT_EXSS_X96 |
                                DCA_EXT_EXSS_XXCH))
        s->profile = FF_PROFILE_DTS_HD_HRA;

    if (!(extensions_mask & DCA_EXT_CORE))
        av_log(s->avctx, AV_LOG_WARNING, "DTS core detection mismatch.\n");
    if ((extensions_mask & DCA_CORE_EXTS) != s->core_ext_mask)
        av_log(s->avctx, AV_LOG_WARNING,
               "DTS extensions detection mismatch (%d, %d)\n",
               extensions_mask & DCA_CORE_EXTS, s->core_ext_mask);

    return 0;
}
Esempio n. 15
0
void CMixer::Init(AVSampleFormat in_avsf, DWORD in_layout, DWORD out_layout, int in_samplerate, int out_samplerate)
{
    // reset parameters
    m_in_avsf        = AV_SAMPLE_FMT_NONE;
    m_in_layout      = 0;
    m_out_layout     = 0;
    m_in_samplerate  = 0;
    m_out_samplerate = 0;
    av_free(m_matrix_dbl);

    // Close Resample Context
    avresample_close(m_pAVRCxt);

    if (in_avsf >= AV_SAMPLE_FMT_U8P && in_avsf <= AV_SAMPLE_FMT_DBLP) { // planar audio is not supported (ffmpeg crashed)
        m_in_avsf_used = AV_SAMPLE_FMT_FLT; // convert to float
    } else {
        m_in_avsf_used = in_avsf;
    }

    int ret = 0;
    // Set options
    av_opt_set_int(m_pAVRCxt, "in_sample_fmt",      m_in_avsf_used,    0);
    av_opt_set_int(m_pAVRCxt, "out_sample_fmt",     AV_SAMPLE_FMT_FLT, 0); // forced float output
    av_opt_set_int(m_pAVRCxt, "in_channel_layout",  in_layout,         0);
    av_opt_set_int(m_pAVRCxt, "out_channel_layout", out_layout,        0);
    av_opt_set_int(m_pAVRCxt, "in_sample_rate",     in_samplerate,     0);
    av_opt_set_int(m_pAVRCxt, "out_sample_rate",    out_samplerate,    0);

    // Open Resample Context
    ret = avresample_open(m_pAVRCxt);
    if (ret < 0) {
        TRACE(_T("Mixer: avresample_open failed\n"));
        return;
    }

    // Create Matrix
    int in_ch  = av_popcount(in_layout);
    int out_ch = av_popcount(out_layout);
    m_matrix_dbl = (double*)av_mallocz(in_ch * out_ch * sizeof(*m_matrix_dbl));
    // expand stereo
    if (in_layout == AV_CH_LAYOUT_STEREO && (out_layout == AV_CH_LAYOUT_QUAD || out_layout == AV_CH_LAYOUT_5POINT1 || out_layout == AV_CH_LAYOUT_7POINT1)) {
        m_matrix_dbl[0] = 1.0;
        m_matrix_dbl[1] = 0.0;
        m_matrix_dbl[2] = 0.0;
        m_matrix_dbl[3] = 1.0;
        if (out_layout == AV_CH_LAYOUT_QUAD) {
            m_matrix_dbl[4] = 0.6666;
            m_matrix_dbl[5] = (-0.2222);
            m_matrix_dbl[6] = (-0.2222);
            m_matrix_dbl[7] = 0.6666;
        } else if (out_layout == AV_CH_LAYOUT_5POINT1 || out_layout == AV_CH_LAYOUT_7POINT1) {
            m_matrix_dbl[4] = 0.5;
            m_matrix_dbl[5] = 0.5;
            m_matrix_dbl[6] = 0.0;
            m_matrix_dbl[7] = 0.0;
            m_matrix_dbl[8] =  0.6666;
            m_matrix_dbl[9] =  (-0.2222);
            m_matrix_dbl[10] = (-0.2222);
            m_matrix_dbl[11] = 0.6666;
            if (out_layout == AV_CH_LAYOUT_7POINT1) {
                m_matrix_dbl[12] = 0.6666;
                m_matrix_dbl[13] = (-0.2222);
                m_matrix_dbl[14] = (-0.2222);
                m_matrix_dbl[15] = 0.6666;
            }
        }
    } else {
        const double center_mix_level   = M_SQRT1_2;
        const double surround_mix_level = M_SQRT1_2;
        const double lfe_mix_level      = M_SQRT1_2;
        const int normalize = 0;
        ret = avresample_build_matrix(in_layout, out_layout, center_mix_level, surround_mix_level, lfe_mix_level, normalize, m_matrix_dbl, in_ch, AV_MATRIX_ENCODING_NONE);
        if (ret < 0) {
            TRACE(_T("Mixer: avresample_build_matrix failed\n"));
            av_free(m_matrix_dbl);
            return;
        }
    }

#ifdef _DEBUG
    CString matrix_str;
    for (int j = 0; j < out_ch; j++) {
        matrix_str.AppendFormat(_T("%d:"), j + 1);
        for (int i = 0; i < in_ch; i++) {
            double k = m_matrix_dbl[j * in_ch + i];
            matrix_str.AppendFormat(_T(" %.4f"), k);
        }
        matrix_str += _T("\n");
    }
    TRACE(matrix_str);
#endif

    // Set Matrix on the context
    ret = avresample_set_matrix(m_pAVRCxt, m_matrix_dbl, in_ch);
    if (ret < 0) {
        TRACE(_T("Mixer: avresample_set_matrix failed\n"));
        av_free(m_matrix_dbl);
        return;
    }

    m_in_avsf        = in_avsf;
    m_in_layout      = in_layout;
    m_out_layout     = out_layout;
    m_in_samplerate  = in_samplerate;
    m_out_samplerate = out_samplerate;
}
Esempio n. 16
0
void CMixer::Init(DWORD out_layout, DWORD in_layout, enum AVSampleFormat in_sf)
{
    avresample_free(&m_pAVRCxt);

    int ret = 0;
    // Allocate Resample Context and set options.
    m_pAVRCxt = avresample_alloc_context();
    av_opt_set_int(m_pAVRCxt, "in_channel_layout", in_layout, 0);
    av_opt_set_int(m_pAVRCxt, "in_sample_fmt", in_sf, 0);
    av_opt_set_int(m_pAVRCxt, "out_channel_layout", out_layout, 0);
    av_opt_set_int(m_pAVRCxt, "out_sample_fmt", AV_SAMPLE_FMT_FLT, 0); // forced float output

    // Open Resample Context
    ret = avresample_open(m_pAVRCxt);
    if (ret < 0) {
        TRACE(_T("Mixer: avresample_open failed\n"));
        avresample_free(&m_pAVRCxt);
        return;
    }

    // Create Matrix
    int in_ch  = av_popcount(in_layout);
    int out_ch = av_popcount(out_layout);
    double* matrix_dbl = (double*)av_mallocz(in_ch * out_ch * sizeof(*matrix_dbl));
    // expand stereo
    if (in_layout == AV_CH_LAYOUT_STEREO && (out_layout == AV_CH_LAYOUT_QUAD || out_layout == AV_CH_LAYOUT_5POINT1 || out_layout == AV_CH_LAYOUT_7POINT1)) {
        matrix_dbl[0] = 1.0;
        matrix_dbl[1] = 0.0;
        matrix_dbl[2] = 0.0;
        matrix_dbl[3] = 1.0;
        if (out_layout == AV_CH_LAYOUT_QUAD) {
            matrix_dbl[4] = 0.5;
            matrix_dbl[5] = (-0.5);
            matrix_dbl[6] = (-0.5);
            matrix_dbl[7] = 0.5;
        } else if (out_layout == AV_CH_LAYOUT_5POINT1 || out_layout == AV_CH_LAYOUT_7POINT1) {
            matrix_dbl[4] = 0.5;
            matrix_dbl[5] = 0.5;
            matrix_dbl[6] = 0.0;
            matrix_dbl[7] = 0.0;
            matrix_dbl[8] = 0.5;
            matrix_dbl[9] = (-0.5);
            matrix_dbl[10] = (-0.5);
            matrix_dbl[11] = 0.5;
            if (out_layout == AV_CH_LAYOUT_7POINT1) {
                matrix_dbl[12] = 0.5;
                matrix_dbl[13] = (-0.5);
                matrix_dbl[14] = (-0.5);
                matrix_dbl[15] = 0.5;
            }
        }
    } else {
        const double center_mix_level   = M_SQRT1_2;
        const double surround_mix_level = M_SQRT1_2;
        const double lfe_mix_level      = M_SQRT1_2;
        const int normalize = 0;
        ret = avresample_build_matrix(in_layout, out_layout, center_mix_level, surround_mix_level, lfe_mix_level, normalize, matrix_dbl, in_ch, AV_MATRIX_ENCODING_NONE);
        if (ret < 0) {
            TRACE(_T("Mixer: avresample_build_matrix failed\n"));
            av_free(matrix_dbl);
            avresample_free(&m_pAVRCxt);
            return;
        }
    }

#ifdef _DEBUG
    CString matrix_str;
    for (int j = 0; j < out_ch; j++) {
        matrix_str.AppendFormat(_T("%d:"), j + 1);
        for (int i = 0; i < in_ch; i++) {
            double k = matrix_dbl[j * in_ch + i];
            matrix_str.AppendFormat(_T(" %.4f"), k);
        }
        matrix_str += _T("\n");
    }
    TRACE(matrix_str);
#endif

    // Set Matrix on the context
    ret = avresample_set_matrix(m_pAVRCxt, matrix_dbl, in_ch);
    av_free(matrix_dbl);
    if (ret < 0) {
        TRACE(_T("Mixer: avresample_set_matrix failed\n"));
        avresample_free(&m_pAVRCxt);
        return;
    }

    last_in_layout  = in_layout;
    last_out_layout = out_layout;
    last_in_sf      = in_sf;
}
Esempio n. 17
0
void CMixer::Init(AVSampleFormat in_avsf, DWORD in_layout, DWORD out_layout, float matrix_norm, int in_samplerate, int out_samplerate)
{
    // reset parameters
    m_in_avsf        = AV_SAMPLE_FMT_NONE;
    m_in_layout      = 0;
    m_out_layout     = 0;
    m_matrix_norm    = 0.0f;
    m_in_samplerate  = 0;
    m_out_samplerate = 0;
    av_free(m_matrix_dbl);

    // Close Resample Context
    avresample_close(m_pAVRCxt);

    int ret = 0;
    // Set options
    av_opt_set_int(m_pAVRCxt, "in_sample_fmt",      in_avsf,           0);
    av_opt_set_int(m_pAVRCxt, "out_sample_fmt",     AV_SAMPLE_FMT_FLT, 0); // forced float output
    av_opt_set_int(m_pAVRCxt, "in_channel_layout",  in_layout,         0);
    av_opt_set_int(m_pAVRCxt, "out_channel_layout", out_layout,        0);
    av_opt_set_int(m_pAVRCxt, "in_sample_rate",     in_samplerate,     0);
    av_opt_set_int(m_pAVRCxt, "out_sample_rate",    out_samplerate,    0);

    // Open Resample Context
    ret = avresample_open(m_pAVRCxt);
    if (ret < 0) {
        TRACE(_T("Mixer: avresample_open failed\n"));
        return;
    }

    // Create Matrix
    int in_ch  = av_popcount(in_layout);
    int out_ch = av_popcount(out_layout);
    m_matrix_dbl = (double*)av_mallocz(in_ch * out_ch * sizeof(*m_matrix_dbl));
    // expand stereo
    if (in_layout == AV_CH_LAYOUT_STEREO && (out_layout == AV_CH_LAYOUT_QUAD || out_layout == AV_CH_LAYOUT_5POINT1 || out_layout == AV_CH_LAYOUT_7POINT1)) {
        m_matrix_dbl[0] = 1.0;
        m_matrix_dbl[1] = 0.0;
        m_matrix_dbl[2] = 0.0;
        m_matrix_dbl[3] = 1.0;
        if (out_layout == AV_CH_LAYOUT_QUAD) {
            m_matrix_dbl[4] = 0.6666;
            m_matrix_dbl[5] = (-0.2222);
            m_matrix_dbl[6] = (-0.2222);
            m_matrix_dbl[7] = 0.6666;
        } else if (out_layout == AV_CH_LAYOUT_5POINT1 || out_layout == AV_CH_LAYOUT_7POINT1) {
            m_matrix_dbl[4] = 0.5;
            m_matrix_dbl[5] = 0.5;
            m_matrix_dbl[6] = 0.0;
            m_matrix_dbl[7] = 0.0;
            m_matrix_dbl[8] =  0.6666;
            m_matrix_dbl[9] = (-0.2222);
            m_matrix_dbl[10] = (-0.2222);
            m_matrix_dbl[11] = 0.6666;
            if (out_layout == AV_CH_LAYOUT_7POINT1) {
                m_matrix_dbl[12] = 0.6666;
                m_matrix_dbl[13] = (-0.2222);
                m_matrix_dbl[14] = (-0.2222);
                m_matrix_dbl[15] = 0.6666;
            }
        }
    } else {
        const double center_mix_level   = M_SQRT1_2;
        const double surround_mix_level = 1.0;
        const double lfe_mix_level      = 1.0;
        const int normalize = 0;
        ret = avresample_build_matrix(in_layout, out_layout, center_mix_level, surround_mix_level, lfe_mix_level, normalize, m_matrix_dbl, in_ch, AV_MATRIX_ENCODING_NONE);
        if (ret < 0) {
            TRACE(_T("Mixer: avresample_build_matrix failed\n"));
            av_free(m_matrix_dbl);
            return;
        }

        // if back channels do not have sound, then divide side channels for the back and side
        if (out_layout == AV_CH_LAYOUT_7POINT1) {
            bool back_no_sound = true;
            for (int i = 0; i < in_ch * 2; i++) {
                if (m_matrix_dbl[4 * in_ch + i] != 0.0) {
                    back_no_sound = false;
                }
            }
            if (back_no_sound) {
                for (int i = 0; i < in_ch * 2; i++) {
                    m_matrix_dbl[4 * in_ch + i] = (m_matrix_dbl[6 * in_ch + i] *= M_SQRT1_2);
                }
            }
        }
    }

    if (matrix_norm > 0.0f && matrix_norm <= 1.0f) { // 0.0 - normalize off; 1.0 - full normalize matrix
        double max_peak = 0;
        for (int j = 0; j < out_ch; j++) {
            double peak = 0;
            for (int i = 0; i < in_ch; i++) {
                peak += fabs(m_matrix_dbl[j * in_ch + i]);
            }
            if (peak > max_peak) {
                max_peak = peak;
            }
        }
        if (max_peak > 1.0) {
            double g = ((max_peak - 1.0) * (1.0 - matrix_norm) + 1.0) / max_peak;
            for (int i = 0, n = in_ch * out_ch; i < n; i++) {
                m_matrix_dbl[i] *= g;
            }
        }
    }

#ifdef _DEBUG
    CString matrix_str = _T("matrix:\n");
    for (int j = 0; j < out_ch; j++) {
        matrix_str.AppendFormat(_T("%d:"), j + 1);
        for (int i = 0; i < in_ch; i++) {
            double k = m_matrix_dbl[j * in_ch + i];
            matrix_str.AppendFormat(_T(" %.4f"), k);
        }
        matrix_str += _T("\n");
    }
    TRACE(matrix_str);
#endif

    // Set Matrix on the context
    ret = avresample_set_matrix(m_pAVRCxt, m_matrix_dbl, in_ch);
    if (ret < 0) {
        TRACE(_T("Mixer: avresample_set_matrix failed\n"));
        av_free(m_matrix_dbl);
        return;
    }

    m_in_avsf        = in_avsf;
    m_in_layout      = in_layout;
    m_out_layout     = out_layout;
    m_matrix_norm    = matrix_norm;
    m_in_samplerate  = in_samplerate;
    m_out_samplerate = out_samplerate;
}