unsafe_libopus/src/
opus_multistream_encoder.rs

1use crate::externs::{free, malloc};
2
3#[derive(Copy, Clone)]
4#[repr(C)]
5pub struct OpusMSEncoder {
6    pub(crate) layout: ChannelLayout,
7    pub(crate) arch: i32,
8    pub(crate) lfe_stream: i32,
9    pub(crate) application: i32,
10    pub(crate) variable_duration: i32,
11    pub(crate) mapping_type: MappingType,
12    pub(crate) bitrate_bps: i32,
13}
14pub type MappingType = u32;
15pub const MAPPING_TYPE_AMBISONICS: MappingType = 2;
16pub const MAPPING_TYPE_SURROUND: MappingType = 1;
17pub const MAPPING_TYPE_NONE: MappingType = 0;
18pub type opus_copy_channel_in_func = Option<
19    unsafe fn(
20        *mut opus_val16,
21        i32,
22        *const core::ffi::c_void,
23        i32,
24        i32,
25        i32,
26        *mut core::ffi::c_void,
27    ) -> (),
28>;
29pub mod arch_h {
30    pub type opus_val32 = f32;
31    pub type opus_val16 = f32;
32}
33pub mod stddef_h {
34    pub type size_t = u64;
35    pub const NULL: i32 = 0;
36}
37
38pub mod cpu_support_h {
39    #[inline]
40    pub unsafe fn opus_select_arch() -> i32 {
41        return 0;
42    }
43}
44pub use self::arch_h::{opus_val16, opus_val32};
45pub use self::cpu_support_h::opus_select_arch;
46pub use self::stddef_h::{size_t, NULL};
47use crate::celt::bands::compute_band_energies;
48use crate::celt::celt::resampling_factor;
49use crate::celt::celt::{
50    CELT_GET_MODE_REQUEST, OPUS_SET_ENERGY_MASK_REQUEST, OPUS_SET_LFE_REQUEST,
51};
52use crate::celt::celt_encoder::celt_preemphasis;
53use crate::celt::mathops::{celt_log2, isqrt32};
54use crate::celt::mdct::clt_mdct_forward_c;
55use crate::celt::modes::OpusCustomMode;
56use crate::celt::pitch::celt_inner_prod_c;
57use crate::celt::quant_bands::amp2Log2;
58use crate::externs::{memcpy, memset};
59use crate::src::analysis::downmix_func;
60use crate::src::opus_defines::{
61    OPUS_ALLOC_FAIL, OPUS_AUTO, OPUS_BAD_ARG, OPUS_BITRATE_MAX, OPUS_BUFFER_TOO_SMALL,
62    OPUS_FRAMESIZE_ARG, OPUS_GET_APPLICATION_REQUEST, OPUS_GET_BANDWIDTH_REQUEST,
63    OPUS_GET_BITRATE_REQUEST, OPUS_GET_COMPLEXITY_REQUEST, OPUS_GET_DTX_REQUEST,
64    OPUS_GET_EXPERT_FRAME_DURATION_REQUEST, OPUS_GET_FINAL_RANGE_REQUEST,
65    OPUS_GET_FORCE_CHANNELS_REQUEST, OPUS_GET_INBAND_FEC_REQUEST, OPUS_GET_LOOKAHEAD_REQUEST,
66    OPUS_GET_LSB_DEPTH_REQUEST, OPUS_GET_PACKET_LOSS_PERC_REQUEST,
67    OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, OPUS_GET_PREDICTION_DISABLED_REQUEST,
68    OPUS_GET_SAMPLE_RATE_REQUEST, OPUS_GET_SIGNAL_REQUEST, OPUS_GET_VBR_CONSTRAINT_REQUEST,
69    OPUS_GET_VBR_REQUEST, OPUS_INTERNAL_ERROR, OPUS_OK, OPUS_RESET_STATE,
70    OPUS_SET_APPLICATION_REQUEST, OPUS_SET_BANDWIDTH_REQUEST, OPUS_SET_BITRATE_REQUEST,
71    OPUS_SET_COMPLEXITY_REQUEST, OPUS_SET_DTX_REQUEST, OPUS_SET_EXPERT_FRAME_DURATION_REQUEST,
72    OPUS_SET_FORCE_CHANNELS_REQUEST, OPUS_SET_INBAND_FEC_REQUEST, OPUS_SET_LSB_DEPTH_REQUEST,
73    OPUS_SET_MAX_BANDWIDTH_REQUEST, OPUS_SET_PACKET_LOSS_PERC_REQUEST,
74    OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, OPUS_SET_PREDICTION_DISABLED_REQUEST,
75    OPUS_SET_SIGNAL_REQUEST, OPUS_SET_VBR_CONSTRAINT_REQUEST, OPUS_SET_VBR_REQUEST,
76    OPUS_UNIMPLEMENTED,
77};
78use crate::src::opus_encoder::{downmix_float, downmix_int, frame_size_select, opus_encode_native};
79use crate::src::opus_multistream::{
80    get_left_channel, get_mono_channel, get_right_channel, validate_layout, ChannelLayout,
81};
82use crate::src::opus_private::{align, OPUS_GET_VOICE_RATIO_REQUEST, OPUS_SET_FORCE_MODE_REQUEST};
83use crate::varargs::VarArgs;
84use crate::{
85    opus_encoder_ctl, opus_encoder_get_size, opus_encoder_init, opus_repacketizer_cat,
86    opus_repacketizer_get_nb_frames, opus_repacketizer_init, opus_repacketizer_out_range_impl,
87    OpusEncoder, OpusRepacketizer,
88};
89
90pub const OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST: i32 = 5120;
91
92#[derive(Copy, Clone)]
93#[repr(C)]
94pub struct VorbisLayout {
95    pub nb_streams: i32,
96    pub nb_coupled_streams: i32,
97    pub mapping: [u8; 8],
98}
99static mut vorbis_mappings: [VorbisLayout; 8] = [
100    {
101        let init = VorbisLayout {
102            nb_streams: 1,
103            nb_coupled_streams: 0,
104            mapping: [0, 0, 0, 0, 0, 0, 0, 0],
105        };
106        init
107    },
108    {
109        let init = VorbisLayout {
110            nb_streams: 1,
111            nb_coupled_streams: 1,
112            mapping: [0, 1, 0, 0, 0, 0, 0, 0],
113        };
114        init
115    },
116    {
117        let init = VorbisLayout {
118            nb_streams: 2,
119            nb_coupled_streams: 1,
120            mapping: [0, 2, 1, 0, 0, 0, 0, 0],
121        };
122        init
123    },
124    {
125        let init = VorbisLayout {
126            nb_streams: 2,
127            nb_coupled_streams: 2,
128            mapping: [0, 1, 2, 3, 0, 0, 0, 0],
129        };
130        init
131    },
132    {
133        let init = VorbisLayout {
134            nb_streams: 3,
135            nb_coupled_streams: 2,
136            mapping: [0, 4, 1, 2, 3, 0, 0, 0],
137        };
138        init
139    },
140    {
141        let init = VorbisLayout {
142            nb_streams: 4,
143            nb_coupled_streams: 2,
144            mapping: [0, 4, 1, 2, 3, 5, 0, 0],
145        };
146        init
147    },
148    {
149        let init = VorbisLayout {
150            nb_streams: 4,
151            nb_coupled_streams: 3,
152            mapping: [0, 4, 1, 2, 3, 5, 6, 0],
153        };
154        init
155    },
156    {
157        let init = VorbisLayout {
158            nb_streams: 5,
159            nb_coupled_streams: 3,
160            mapping: [0, 6, 1, 2, 3, 4, 5, 7],
161        };
162        init
163    },
164];
165unsafe fn ms_get_preemph_mem(st: *mut OpusMSEncoder) -> *mut opus_val32 {
166    let mut s: i32 = 0;
167    let mut ptr: *mut i8 = 0 as *mut i8;
168    let mut coupled_size: i32 = 0;
169    let mut mono_size: i32 = 0;
170    coupled_size = opus_encoder_get_size(2);
171    mono_size = opus_encoder_get_size(1);
172    ptr = (st as *mut i8)
173        .offset(align(::core::mem::size_of::<OpusMSEncoder>() as u64 as i32) as isize);
174    s = 0;
175    while s < (*st).layout.nb_streams {
176        if s < (*st).layout.nb_coupled_streams {
177            ptr = ptr.offset(align(coupled_size) as isize);
178        } else {
179            ptr = ptr.offset(align(mono_size) as isize);
180        }
181        s += 1;
182    }
183    return ptr.offset(
184        (((*st).layout.nb_channels * 120) as u64)
185            .wrapping_mul(::core::mem::size_of::<opus_val32>() as u64) as isize,
186    ) as *mut core::ffi::c_void as *mut opus_val32;
187}
188unsafe fn ms_get_window_mem(st: *mut OpusMSEncoder) -> *mut opus_val32 {
189    let mut s: i32 = 0;
190    let mut ptr: *mut i8 = 0 as *mut i8;
191    let mut coupled_size: i32 = 0;
192    let mut mono_size: i32 = 0;
193    coupled_size = opus_encoder_get_size(2);
194    mono_size = opus_encoder_get_size(1);
195    ptr = (st as *mut i8)
196        .offset(align(::core::mem::size_of::<OpusMSEncoder>() as u64 as i32) as isize);
197    s = 0;
198    while s < (*st).layout.nb_streams {
199        if s < (*st).layout.nb_coupled_streams {
200            ptr = ptr.offset(align(coupled_size) as isize);
201        } else {
202            ptr = ptr.offset(align(mono_size) as isize);
203        }
204        s += 1;
205    }
206    return ptr as *mut core::ffi::c_void as *mut opus_val32;
207}
208unsafe fn validate_ambisonics(
209    nb_channels: i32,
210    nb_streams: *mut i32,
211    nb_coupled_streams: *mut i32,
212) -> i32 {
213    let mut order_plus_one: i32 = 0;
214    let mut acn_channels: i32 = 0;
215    let mut nondiegetic_channels: i32 = 0;
216    if nb_channels < 1 || nb_channels > 227 {
217        return 0;
218    }
219    order_plus_one = isqrt32(nb_channels as u32) as i32;
220    acn_channels = order_plus_one * order_plus_one;
221    nondiegetic_channels = nb_channels - acn_channels;
222    if nondiegetic_channels != 0 && nondiegetic_channels != 2 {
223        return 0;
224    }
225    if !nb_streams.is_null() {
226        *nb_streams = acn_channels + (nondiegetic_channels != 0) as i32;
227    }
228    if !nb_coupled_streams.is_null() {
229        *nb_coupled_streams = (nondiegetic_channels != 0) as i32;
230    }
231    return 1;
232}
233unsafe fn validate_encoder_layout(layout: *const ChannelLayout) -> i32 {
234    let mut s: i32 = 0;
235    s = 0;
236    while s < (*layout).nb_streams {
237        if s < (*layout).nb_coupled_streams {
238            if get_left_channel(layout, s, -1) == -1 {
239                return 0;
240            }
241            if get_right_channel(layout, s, -1) == -1 {
242                return 0;
243            }
244        } else if get_mono_channel(layout, s, -1) == -1 {
245            return 0;
246        }
247        s += 1;
248    }
249    return 1;
250}
251unsafe fn channel_pos(channels: i32, pos: *mut i32) {
252    if channels == 4 {
253        *pos.offset(0 as isize) = 1;
254        *pos.offset(1 as isize) = 3;
255        *pos.offset(2 as isize) = 1;
256        *pos.offset(3 as isize) = 3;
257    } else if channels == 3 || channels == 5 || channels == 6 {
258        *pos.offset(0 as isize) = 1;
259        *pos.offset(1 as isize) = 2;
260        *pos.offset(2 as isize) = 3;
261        *pos.offset(3 as isize) = 1;
262        *pos.offset(4 as isize) = 3;
263        *pos.offset(5 as isize) = 0;
264    } else if channels == 7 {
265        *pos.offset(0 as isize) = 1;
266        *pos.offset(1 as isize) = 2;
267        *pos.offset(2 as isize) = 3;
268        *pos.offset(3 as isize) = 1;
269        *pos.offset(4 as isize) = 3;
270        *pos.offset(5 as isize) = 2;
271        *pos.offset(6 as isize) = 0;
272    } else if channels == 8 {
273        *pos.offset(0 as isize) = 1;
274        *pos.offset(1 as isize) = 2;
275        *pos.offset(2 as isize) = 3;
276        *pos.offset(3 as isize) = 1;
277        *pos.offset(4 as isize) = 3;
278        *pos.offset(5 as isize) = 1;
279        *pos.offset(6 as isize) = 3;
280        *pos.offset(7 as isize) = 0;
281    }
282}
283unsafe fn logSum(a: opus_val16, b: opus_val16) -> opus_val16 {
284    let mut max: opus_val16 = 0.;
285    let mut diff: opus_val32 = 0.;
286    let mut frac: opus_val16 = 0.;
287    static mut diff_table: [opus_val16; 17] = [
288        0.5000000f32,
289        0.2924813f32,
290        0.1609640f32,
291        0.0849625f32,
292        0.0437314f32,
293        0.0221971f32,
294        0.0111839f32,
295        0.0056136f32,
296        0.0028123f32,
297        0.,
298        0.,
299        0.,
300        0.,
301        0.,
302        0.,
303        0.,
304        0.,
305    ];
306    let mut low: i32 = 0;
307    if a > b {
308        max = a;
309        diff = a - b;
310    } else {
311        max = b;
312        diff = b - a;
313    }
314    if !(diff < 8.0f32) {
315        return max;
316    }
317    low = (2 as f32 * diff).floor() as i32;
318    frac = 2 as f32 * diff - low as f32;
319    return max
320        + diff_table[low as usize]
321        + frac * (diff_table[(low + 1) as usize] - diff_table[low as usize]);
322}
323pub unsafe fn surround_analysis(
324    celt_mode: *const OpusCustomMode,
325    pcm: *const core::ffi::c_void,
326    bandLogE: *mut opus_val16,
327    mem: *mut opus_val32,
328    preemph_mem: *mut opus_val32,
329    len: i32,
330    overlap: i32,
331    channels: i32,
332    rate: i32,
333    copy_channel_in: opus_copy_channel_in_func,
334    arch: i32,
335) {
336    let mut c: i32 = 0;
337    let mut i: i32 = 0;
338    let mut LM: i32 = 0;
339    let mut pos: [i32; 8] = [0, 0, 0, 0, 0, 0, 0, 0];
340    let mut upsample: i32 = 0;
341    let mut frame_size: i32 = 0;
342    let mut freq_size: i32 = 0;
343    let mut channel_offset: opus_val16 = 0.;
344    let mut bandE: [opus_val32; 21] = [0.; 21];
345    let mut maskLogE: [[opus_val16; 21]; 3] = [[0.; 21]; 3];
346    upsample = resampling_factor(rate);
347    frame_size = len * upsample;
348    freq_size = if (960) < frame_size { 960 } else { frame_size };
349    LM = 0;
350    while LM < (*celt_mode).maxLM {
351        if (*celt_mode).shortMdctSize << LM == frame_size {
352            break;
353        }
354        LM += 1;
355    }
356    let vla = (frame_size + overlap) as usize;
357    let mut in_0: Vec<opus_val32> = ::std::vec::from_elem(0., vla);
358    let vla_0 = len as usize;
359    let mut x: Vec<opus_val16> = ::std::vec::from_elem(0., vla_0);
360    let vla_1 = freq_size as usize;
361    let mut freq: Vec<opus_val32> = ::std::vec::from_elem(0., vla_1);
362    channel_pos(channels, pos.as_mut_ptr());
363    c = 0;
364    while c < 3 {
365        i = 0;
366        while i < 21 {
367            maskLogE[c as usize][i as usize] = -28.0f32;
368            i += 1;
369        }
370        c += 1;
371    }
372    c = 0;
373    while c < channels {
374        let mut frame: i32 = 0;
375        let nb_frames: i32 = frame_size / freq_size;
376        assert!(nb_frames * freq_size == frame_size);
377        memcpy(
378            in_0.as_mut_ptr() as *mut core::ffi::c_void,
379            mem.offset((c * overlap) as isize) as *const core::ffi::c_void,
380            (overlap as u64)
381                .wrapping_mul(::core::mem::size_of::<opus_val32>() as u64)
382                .wrapping_add(
383                    (0 * in_0
384                        .as_mut_ptr()
385                        .offset_from(mem.offset((c * overlap) as isize))
386                        as i64) as u64,
387                ),
388        );
389        (Some(copy_channel_in.expect("non-null function pointer")))
390            .expect("non-null function pointer")(
391            x.as_mut_ptr(),
392            1,
393            pcm,
394            channels,
395            c,
396            len,
397            NULL as *mut core::ffi::c_void,
398        );
399        celt_preemphasis(
400            x.as_mut_ptr(),
401            in_0.as_mut_ptr().offset(overlap as isize),
402            frame_size,
403            1,
404            upsample,
405            ((*celt_mode).preemph).as_ptr(),
406            preemph_mem.offset(c as isize),
407            0,
408        );
409        let mut sum: opus_val32 = 0.;
410        sum = celt_inner_prod_c(in_0.as_mut_ptr(), in_0.as_mut_ptr(), frame_size + overlap);
411        if !(sum < 1e18f32) || sum != sum {
412            memset(
413                in_0.as_mut_ptr() as *mut core::ffi::c_void,
414                0,
415                ((frame_size + overlap) as u64)
416                    .wrapping_mul(::core::mem::size_of::<opus_val32>() as u64),
417            );
418            *preemph_mem.offset(c as isize) = 0 as opus_val32;
419        }
420        memset(
421            bandE.as_mut_ptr() as *mut core::ffi::c_void,
422            0,
423            21_u64.wrapping_mul(::core::mem::size_of::<opus_val32>() as u64),
424        );
425        frame = 0;
426        while frame < nb_frames {
427            let mut tmpE: [opus_val32; 21] = [0.; 21];
428            clt_mdct_forward_c(
429                &(*celt_mode).mdct,
430                in_0.as_mut_ptr().offset((960 * frame) as isize),
431                freq.as_mut_ptr(),
432                (*celt_mode).window,
433                overlap,
434                (*celt_mode).maxLM - LM,
435                1,
436                arch,
437            );
438            if upsample != 1 {
439                let bound: i32 = freq_size / upsample;
440                i = 0;
441                while i < bound {
442                    let ref mut fresh0 = *freq.as_mut_ptr().offset(i as isize);
443                    *fresh0 *= upsample as f32;
444                    i += 1;
445                }
446                while i < freq_size {
447                    *freq.as_mut_ptr().offset(i as isize) = 0 as opus_val32;
448                    i += 1;
449                }
450            }
451            compute_band_energies(
452                celt_mode,
453                freq.as_mut_ptr(),
454                tmpE.as_mut_ptr(),
455                21,
456                1,
457                LM,
458                arch,
459            );
460            i = 0;
461            while i < 21 {
462                bandE[i as usize] = if bandE[i as usize] > tmpE[i as usize] {
463                    bandE[i as usize]
464                } else {
465                    tmpE[i as usize]
466                };
467                i += 1;
468            }
469            frame += 1;
470        }
471        amp2Log2(
472            celt_mode,
473            21,
474            21,
475            bandE.as_mut_ptr(),
476            bandLogE.offset((21 * c) as isize),
477            1,
478        );
479        i = 1;
480        while i < 21 {
481            *bandLogE.offset((21 * c + i) as isize) = if *bandLogE.offset((21 * c + i) as isize)
482                > *bandLogE.offset((21 * c + i - 1) as isize) - 1.0f32
483            {
484                *bandLogE.offset((21 * c + i) as isize)
485            } else {
486                *bandLogE.offset((21 * c + i - 1) as isize) - 1.0f32
487            };
488            i += 1;
489        }
490        i = 19;
491        while i >= 0 {
492            *bandLogE.offset((21 * c + i) as isize) = if *bandLogE.offset((21 * c + i) as isize)
493                > *bandLogE.offset((21 * c + i + 1) as isize) - 2.0f32
494            {
495                *bandLogE.offset((21 * c + i) as isize)
496            } else {
497                *bandLogE.offset((21 * c + i + 1) as isize) - 2.0f32
498            };
499            i -= 1;
500        }
501        if pos[c as usize] == 1 {
502            i = 0;
503            while i < 21 {
504                maskLogE[0 as usize][i as usize] = logSum(
505                    maskLogE[0 as usize][i as usize],
506                    *bandLogE.offset((21 * c + i) as isize),
507                );
508                i += 1;
509            }
510        } else if pos[c as usize] == 3 {
511            i = 0;
512            while i < 21 {
513                maskLogE[2 as usize][i as usize] = logSum(
514                    maskLogE[2 as usize][i as usize],
515                    *bandLogE.offset((21 * c + i) as isize),
516                );
517                i += 1;
518            }
519        } else if pos[c as usize] == 2 {
520            i = 0;
521            while i < 21 {
522                maskLogE[0 as usize][i as usize] = logSum(
523                    maskLogE[0 as usize][i as usize],
524                    *bandLogE.offset((21 * c + i) as isize) - 0.5f32,
525                );
526                maskLogE[2 as usize][i as usize] = logSum(
527                    maskLogE[2 as usize][i as usize],
528                    *bandLogE.offset((21 * c + i) as isize) - 0.5f32,
529                );
530                i += 1;
531            }
532        }
533        memcpy(
534            mem.offset((c * overlap) as isize) as *mut core::ffi::c_void,
535            in_0.as_mut_ptr().offset(frame_size as isize) as *const core::ffi::c_void,
536            (overlap as u64)
537                .wrapping_mul(::core::mem::size_of::<opus_val32>() as u64)
538                .wrapping_add(
539                    (0 * mem
540                        .offset((c * overlap) as isize)
541                        .offset_from(in_0.as_mut_ptr().offset(frame_size as isize))
542                        as i64) as u64,
543                ),
544        );
545        c += 1;
546    }
547    i = 0;
548    while i < 21 {
549        maskLogE[1 as usize][i as usize] =
550            if maskLogE[0 as usize][i as usize] < maskLogE[2 as usize][i as usize] {
551                maskLogE[0 as usize][i as usize]
552            } else {
553                maskLogE[2 as usize][i as usize]
554            };
555        i += 1;
556    }
557    channel_offset = 0.5f32 * celt_log2(2.0f32 / (channels - 1) as f32);
558    c = 0;
559    while c < 3 {
560        i = 0;
561        while i < 21 {
562            maskLogE[c as usize][i as usize] += channel_offset;
563            i += 1;
564        }
565        c += 1;
566    }
567    c = 0;
568    while c < channels {
569        let mut mask: *mut opus_val16 = 0 as *mut opus_val16;
570        if pos[c as usize] != 0 {
571            mask = &mut *(*maskLogE
572                .as_mut_ptr()
573                .offset((*pos.as_mut_ptr().offset(c as isize) - 1) as isize))
574            .as_mut_ptr()
575            .offset(0 as isize) as *mut opus_val16;
576            i = 0;
577            while i < 21 {
578                *bandLogE.offset((21 * c + i) as isize) =
579                    *bandLogE.offset((21 * c + i) as isize) - *mask.offset(i as isize);
580                i += 1;
581            }
582        } else {
583            i = 0;
584            while i < 21 {
585                *bandLogE.offset((21 * c + i) as isize) = 0 as opus_val16;
586                i += 1;
587            }
588        }
589        c += 1;
590    }
591}
592pub unsafe fn opus_multistream_encoder_get_size(nb_streams: i32, nb_coupled_streams: i32) -> i32 {
593    let mut coupled_size: i32 = 0;
594    let mut mono_size: i32 = 0;
595    if nb_streams < 1 || nb_coupled_streams > nb_streams || nb_coupled_streams < 0 {
596        return 0;
597    }
598    coupled_size = opus_encoder_get_size(2);
599    mono_size = opus_encoder_get_size(1);
600    return align(::core::mem::size_of::<OpusMSEncoder>() as u64 as i32)
601        + nb_coupled_streams * align(coupled_size)
602        + (nb_streams - nb_coupled_streams) * align(mono_size);
603}
604pub unsafe fn opus_multistream_surround_encoder_get_size(
605    channels: i32,
606    mapping_family: i32,
607) -> i32 {
608    let mut nb_streams: i32 = 0;
609    let mut nb_coupled_streams: i32 = 0;
610    let mut size: i32 = 0;
611    if mapping_family == 0 {
612        if channels == 1 {
613            nb_streams = 1;
614            nb_coupled_streams = 0;
615        } else if channels == 2 {
616            nb_streams = 1;
617            nb_coupled_streams = 1;
618        } else {
619            return 0;
620        }
621    } else if mapping_family == 1 && channels <= 8 && channels >= 1 {
622        nb_streams = vorbis_mappings[(channels - 1) as usize].nb_streams;
623        nb_coupled_streams = vorbis_mappings[(channels - 1) as usize].nb_coupled_streams;
624    } else if mapping_family == 255 {
625        nb_streams = channels;
626        nb_coupled_streams = 0;
627    } else if mapping_family == 2 {
628        if validate_ambisonics(channels, &mut nb_streams, &mut nb_coupled_streams) == 0 {
629            return 0;
630        }
631    } else {
632        return 0;
633    }
634    size = opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams);
635    if channels > 2 {
636        size = (size as u64).wrapping_add(
637            (channels as u64).wrapping_mul(
638                120_u64
639                    .wrapping_mul(::core::mem::size_of::<opus_val32>() as u64)
640                    .wrapping_add(::core::mem::size_of::<opus_val32>() as u64),
641            ),
642        ) as i32 as i32;
643    }
644    return size;
645}
646unsafe fn opus_multistream_encoder_init_impl(
647    st: *mut OpusMSEncoder,
648    Fs: i32,
649    channels: i32,
650    streams: i32,
651    coupled_streams: i32,
652    mapping: *const u8,
653    application: i32,
654    mapping_type: MappingType,
655) -> i32 {
656    let mut coupled_size: i32 = 0;
657    let mut mono_size: i32 = 0;
658    let mut i: i32 = 0;
659    let mut ret: i32 = 0;
660    let mut ptr: *mut i8 = 0 as *mut i8;
661    if channels > 255
662        || channels < 1
663        || coupled_streams > streams
664        || streams < 1
665        || coupled_streams < 0
666        || streams > 255 - coupled_streams
667    {
668        return OPUS_BAD_ARG;
669    }
670    (*st).arch = opus_select_arch();
671    (*st).layout.nb_channels = channels;
672    (*st).layout.nb_streams = streams;
673    (*st).layout.nb_coupled_streams = coupled_streams;
674    if mapping_type as u32 != MAPPING_TYPE_SURROUND as i32 as u32 {
675        (*st).lfe_stream = -1;
676    }
677    (*st).bitrate_bps = OPUS_AUTO;
678    (*st).application = application;
679    (*st).variable_duration = OPUS_FRAMESIZE_ARG;
680    i = 0;
681    while i < (*st).layout.nb_channels {
682        (*st).layout.mapping[i as usize] = *mapping.offset(i as isize);
683        i += 1;
684    }
685    if validate_layout(&mut (*st).layout) == 0 {
686        return OPUS_BAD_ARG;
687    }
688    if mapping_type as u32 == MAPPING_TYPE_SURROUND as i32 as u32
689        && validate_encoder_layout(&mut (*st).layout) == 0
690    {
691        return OPUS_BAD_ARG;
692    }
693    if mapping_type as u32 == MAPPING_TYPE_AMBISONICS as i32 as u32
694        && validate_ambisonics((*st).layout.nb_channels, NULL as *mut i32, NULL as *mut i32) == 0
695    {
696        return OPUS_BAD_ARG;
697    }
698    ptr = (st as *mut i8)
699        .offset(align(::core::mem::size_of::<OpusMSEncoder>() as u64 as i32) as isize);
700    coupled_size = opus_encoder_get_size(2);
701    mono_size = opus_encoder_get_size(1);
702    i = 0;
703    while i < (*st).layout.nb_coupled_streams {
704        ret = opus_encoder_init(ptr as *mut OpusEncoder, Fs, 2, application);
705        if ret != OPUS_OK {
706            return ret;
707        }
708        if i == (*st).lfe_stream {
709            opus_encoder_ctl!(ptr as *mut OpusEncoder, OPUS_SET_LFE_REQUEST, 1,);
710        }
711        ptr = ptr.offset(align(coupled_size) as isize);
712        i += 1;
713    }
714    while i < (*st).layout.nb_streams {
715        ret = opus_encoder_init(ptr as *mut OpusEncoder, Fs, 1, application);
716        if i == (*st).lfe_stream {
717            opus_encoder_ctl!(ptr as *mut OpusEncoder, OPUS_SET_LFE_REQUEST, 1,);
718        }
719        if ret != OPUS_OK {
720            return ret;
721        }
722        ptr = ptr.offset(align(mono_size) as isize);
723        i += 1;
724    }
725    if mapping_type as u32 == MAPPING_TYPE_SURROUND as i32 as u32 {
726        memset(
727            ms_get_preemph_mem(st) as *mut core::ffi::c_void,
728            0,
729            (channels as u64).wrapping_mul(::core::mem::size_of::<opus_val32>() as u64),
730        );
731        memset(
732            ms_get_window_mem(st) as *mut core::ffi::c_void,
733            0,
734            ((channels * 120) as u64).wrapping_mul(::core::mem::size_of::<opus_val32>() as u64),
735        );
736    }
737    (*st).mapping_type = mapping_type;
738    return OPUS_OK;
739}
740pub unsafe fn opus_multistream_encoder_init(
741    st: *mut OpusMSEncoder,
742    Fs: i32,
743    channels: i32,
744    streams: i32,
745    coupled_streams: i32,
746    mapping: *const u8,
747    application: i32,
748) -> i32 {
749    return opus_multistream_encoder_init_impl(
750        st,
751        Fs,
752        channels,
753        streams,
754        coupled_streams,
755        mapping,
756        application,
757        MAPPING_TYPE_NONE,
758    );
759}
760pub unsafe fn opus_multistream_surround_encoder_init(
761    st: *mut OpusMSEncoder,
762    Fs: i32,
763    channels: i32,
764    mapping_family: i32,
765    streams: *mut i32,
766    coupled_streams: *mut i32,
767    mapping: *mut u8,
768    application: i32,
769) -> i32 {
770    let mut mapping_type: MappingType = MAPPING_TYPE_NONE;
771    if channels > 255 || channels < 1 {
772        return OPUS_BAD_ARG;
773    }
774    (*st).lfe_stream = -1;
775    if mapping_family == 0 {
776        if channels == 1 {
777            *streams = 1;
778            *coupled_streams = 0;
779            *mapping.offset(0 as isize) = 0;
780        } else if channels == 2 {
781            *streams = 1;
782            *coupled_streams = 1;
783            *mapping.offset(0 as isize) = 0;
784            *mapping.offset(1 as isize) = 1;
785        } else {
786            return OPUS_UNIMPLEMENTED;
787        }
788    } else if mapping_family == 1 && channels <= 8 && channels >= 1 {
789        let mut i: i32 = 0;
790        *streams = vorbis_mappings[(channels - 1) as usize].nb_streams;
791        *coupled_streams = vorbis_mappings[(channels - 1) as usize].nb_coupled_streams;
792        i = 0;
793        while i < channels {
794            *mapping.offset(i as isize) =
795                vorbis_mappings[(channels - 1) as usize].mapping[i as usize];
796            i += 1;
797        }
798        if channels >= 6 {
799            (*st).lfe_stream = *streams - 1;
800        }
801    } else if mapping_family == 255 {
802        let mut i_0: i32 = 0;
803        *streams = channels;
804        *coupled_streams = 0;
805        i_0 = 0;
806        while i_0 < channels {
807            *mapping.offset(i_0 as isize) = i_0 as u8;
808            i_0 += 1;
809        }
810    } else if mapping_family == 2 {
811        let mut i_1: i32 = 0;
812        if validate_ambisonics(channels, streams, coupled_streams) == 0 {
813            return OPUS_BAD_ARG;
814        }
815        i_1 = 0;
816        while i_1 < *streams - *coupled_streams {
817            *mapping.offset(i_1 as isize) = (i_1 + *coupled_streams * 2) as u8;
818            i_1 += 1;
819        }
820        i_1 = 0;
821        while i_1 < *coupled_streams * 2 {
822            *mapping.offset((i_1 + (*streams - *coupled_streams)) as isize) = i_1 as u8;
823            i_1 += 1;
824        }
825    } else {
826        return OPUS_UNIMPLEMENTED;
827    }
828    if channels > 2 && mapping_family == 1 {
829        mapping_type = MAPPING_TYPE_SURROUND;
830    } else if mapping_family == 2 {
831        mapping_type = MAPPING_TYPE_AMBISONICS;
832    } else {
833        mapping_type = MAPPING_TYPE_NONE;
834    }
835    return opus_multistream_encoder_init_impl(
836        st,
837        Fs,
838        channels,
839        *streams,
840        *coupled_streams,
841        mapping,
842        application,
843        mapping_type,
844    );
845}
846pub unsafe fn opus_multistream_encoder_create(
847    Fs: i32,
848    channels: i32,
849    streams: i32,
850    coupled_streams: i32,
851    mapping: *const u8,
852    application: i32,
853    error: *mut i32,
854) -> *mut OpusMSEncoder {
855    let mut ret: i32 = 0;
856    let mut st: *mut OpusMSEncoder = 0 as *mut OpusMSEncoder;
857    if channels > 255
858        || channels < 1
859        || coupled_streams > streams
860        || streams < 1
861        || coupled_streams < 0
862        || streams > 255 - coupled_streams
863    {
864        if !error.is_null() {
865            *error = OPUS_BAD_ARG;
866        }
867        return NULL as *mut OpusMSEncoder;
868    }
869    st = malloc(opus_multistream_encoder_get_size(streams, coupled_streams) as size_t)
870        as *mut OpusMSEncoder;
871    if st.is_null() {
872        if !error.is_null() {
873            *error = OPUS_ALLOC_FAIL;
874        }
875        return NULL as *mut OpusMSEncoder;
876    }
877    ret = opus_multistream_encoder_init(
878        st,
879        Fs,
880        channels,
881        streams,
882        coupled_streams,
883        mapping,
884        application,
885    );
886    if ret != OPUS_OK {
887        free(st as *mut core::ffi::c_void);
888        st = NULL as *mut OpusMSEncoder;
889    }
890    if !error.is_null() {
891        *error = ret;
892    }
893    return st;
894}
895pub unsafe fn opus_multistream_surround_encoder_create(
896    Fs: i32,
897    channels: i32,
898    mapping_family: i32,
899    streams: *mut i32,
900    coupled_streams: *mut i32,
901    mapping: *mut u8,
902    application: i32,
903    error: *mut i32,
904) -> *mut OpusMSEncoder {
905    let mut ret: i32 = 0;
906    let mut size: i32 = 0;
907    let mut st: *mut OpusMSEncoder = 0 as *mut OpusMSEncoder;
908    if channels > 255 || channels < 1 {
909        if !error.is_null() {
910            *error = OPUS_BAD_ARG;
911        }
912        return NULL as *mut OpusMSEncoder;
913    }
914    size = opus_multistream_surround_encoder_get_size(channels, mapping_family);
915    if size == 0 {
916        if !error.is_null() {
917            *error = OPUS_UNIMPLEMENTED;
918        }
919        return NULL as *mut OpusMSEncoder;
920    }
921    st = malloc(size as size_t) as *mut OpusMSEncoder;
922    if st.is_null() {
923        if !error.is_null() {
924            *error = OPUS_ALLOC_FAIL;
925        }
926        return NULL as *mut OpusMSEncoder;
927    }
928    ret = opus_multistream_surround_encoder_init(
929        st,
930        Fs,
931        channels,
932        mapping_family,
933        streams,
934        coupled_streams,
935        mapping,
936        application,
937    );
938    if ret != OPUS_OK {
939        free(st as *mut core::ffi::c_void);
940        st = NULL as *mut OpusMSEncoder;
941    }
942    if !error.is_null() {
943        *error = ret;
944    }
945    return st;
946}
947unsafe fn surround_rate_allocation(
948    st: *mut OpusMSEncoder,
949    rate: *mut i32,
950    frame_size: i32,
951    Fs: i32,
952) {
953    let mut i: i32 = 0;
954    let mut channel_rate: i32 = 0;
955    let mut stream_offset: i32 = 0;
956    let mut lfe_offset: i32 = 0;
957    let mut coupled_ratio: i32 = 0;
958    let mut lfe_ratio: i32 = 0;
959    let mut nb_lfe: i32 = 0;
960    let mut nb_uncoupled: i32 = 0;
961    let mut nb_coupled: i32 = 0;
962    let mut nb_normal: i32 = 0;
963    let mut channel_offset: i32 = 0;
964    let mut bitrate: i32 = 0;
965    let mut total: i32 = 0;
966    nb_lfe = ((*st).lfe_stream != -1) as i32;
967    nb_coupled = (*st).layout.nb_coupled_streams;
968    nb_uncoupled = (*st).layout.nb_streams - nb_coupled - nb_lfe;
969    nb_normal = 2 * nb_coupled + nb_uncoupled;
970    channel_offset = 40
971        * (if 50 > Fs / frame_size {
972            50
973        } else {
974            Fs / frame_size
975        });
976    if (*st).bitrate_bps == OPUS_AUTO {
977        bitrate = nb_normal * (channel_offset + Fs + 10000) + 8000 * nb_lfe;
978    } else if (*st).bitrate_bps == OPUS_BITRATE_MAX {
979        bitrate = nb_normal * 300000 + nb_lfe * 128000;
980    } else {
981        bitrate = (*st).bitrate_bps;
982    }
983    lfe_offset = (if (bitrate / 20) < 3000 {
984        bitrate / 20
985    } else {
986        3000
987    }) + 15
988        * (if 50 > Fs / frame_size {
989            50
990        } else {
991            Fs / frame_size
992        });
993    stream_offset = (bitrate - channel_offset * nb_normal - lfe_offset * nb_lfe) / nb_normal / 2;
994    stream_offset = if 0
995        > (if (20000) < stream_offset {
996            20000
997        } else {
998            stream_offset
999        }) {
1000        0
1001    } else if (20000) < stream_offset {
1002        20000
1003    } else {
1004        stream_offset
1005    };
1006    coupled_ratio = 512;
1007    lfe_ratio = 32;
1008    total = (nb_uncoupled << 8) + coupled_ratio * nb_coupled + nb_lfe * lfe_ratio;
1009    channel_rate = (256
1010        * (bitrate
1011            - lfe_offset * nb_lfe
1012            - stream_offset * (nb_coupled + nb_uncoupled)
1013            - channel_offset * nb_normal) as i64
1014        / total as i64) as i32;
1015    i = 0;
1016    while i < (*st).layout.nb_streams {
1017        if i < (*st).layout.nb_coupled_streams {
1018            *rate.offset(i as isize) = 2 * channel_offset
1019                + (if 0 > stream_offset + (channel_rate * coupled_ratio >> 8) {
1020                    0
1021                } else {
1022                    stream_offset + (channel_rate * coupled_ratio >> 8)
1023                });
1024        } else if i != (*st).lfe_stream {
1025            *rate.offset(i as isize) = channel_offset
1026                + (if 0 > stream_offset + channel_rate {
1027                    0
1028                } else {
1029                    stream_offset + channel_rate
1030                });
1031        } else {
1032            *rate.offset(i as isize) = if 0 > lfe_offset + (channel_rate * lfe_ratio >> 8) {
1033                0
1034            } else {
1035                lfe_offset + (channel_rate * lfe_ratio >> 8)
1036            };
1037        }
1038        i += 1;
1039    }
1040}
1041unsafe fn ambisonics_rate_allocation(
1042    st: *mut OpusMSEncoder,
1043    rate: *mut i32,
1044    frame_size: i32,
1045    Fs: i32,
1046) {
1047    let mut i: i32 = 0;
1048    let mut total_rate: i32 = 0;
1049    let mut per_stream_rate: i32 = 0;
1050    let nb_channels: i32 = (*st).layout.nb_streams + (*st).layout.nb_coupled_streams;
1051    if (*st).bitrate_bps == OPUS_AUTO {
1052        total_rate = ((*st).layout.nb_coupled_streams + (*st).layout.nb_streams)
1053            * (Fs + 60 * Fs / frame_size)
1054            + (*st).layout.nb_streams * 15000;
1055    } else if (*st).bitrate_bps == OPUS_BITRATE_MAX {
1056        total_rate = nb_channels * 320000;
1057    } else {
1058        total_rate = (*st).bitrate_bps;
1059    }
1060    per_stream_rate = total_rate / (*st).layout.nb_streams;
1061    i = 0;
1062    while i < (*st).layout.nb_streams {
1063        *rate.offset(i as isize) = per_stream_rate;
1064        i += 1;
1065    }
1066}
1067unsafe fn rate_allocation(st: *mut OpusMSEncoder, rate: *mut i32, frame_size: i32) -> i32 {
1068    let mut i: i32 = 0;
1069    let mut rate_sum: i32 = 0;
1070    let mut Fs: i32 = 0;
1071    let mut ptr: *mut i8 = 0 as *mut i8;
1072    ptr = (st as *mut i8)
1073        .offset(align(::core::mem::size_of::<OpusMSEncoder>() as u64 as i32) as isize);
1074    opus_encoder_ctl!(
1075        ptr as *mut OpusEncoder,
1076        OPUS_GET_SAMPLE_RATE_REQUEST,
1077        &mut Fs
1078    );
1079    if (*st).mapping_type as u32 == MAPPING_TYPE_AMBISONICS as i32 as u32 {
1080        ambisonics_rate_allocation(st, rate, frame_size, Fs);
1081    } else {
1082        surround_rate_allocation(st, rate, frame_size, Fs);
1083    }
1084    i = 0;
1085    while i < (*st).layout.nb_streams {
1086        *rate.offset(i as isize) = if *rate.offset(i as isize) > 500 {
1087            *rate.offset(i as isize)
1088        } else {
1089            500
1090        };
1091        rate_sum += *rate.offset(i as isize);
1092        i += 1;
1093    }
1094    return rate_sum;
1095}
1096pub unsafe fn opus_multistream_encode_native(
1097    st: *mut OpusMSEncoder,
1098    copy_channel_in: opus_copy_channel_in_func,
1099    pcm: *const core::ffi::c_void,
1100    analysis_frame_size: i32,
1101    mut data: *mut u8,
1102    mut max_data_bytes: i32,
1103    lsb_depth: i32,
1104    downmix: downmix_func,
1105    float_api: i32,
1106    user_data: *mut core::ffi::c_void,
1107) -> i32 {
1108    let mut Fs: i32 = 0;
1109    let mut coupled_size: i32 = 0;
1110    let mut mono_size: i32 = 0;
1111    let mut s: i32 = 0;
1112    let mut ptr: *mut i8 = 0 as *mut i8;
1113    let mut tot_size: i32 = 0;
1114    let mut tmp_data: [u8; 7662] = [0; 7662];
1115    let mut rp: OpusRepacketizer = OpusRepacketizer {
1116        toc: 0,
1117        nb_frames: 0,
1118        frames: [0 as *const u8; 48],
1119        len: [0; 48],
1120        framesize: 0,
1121    };
1122    let mut vbr: i32 = 0;
1123    let mut celt_mode: *const OpusCustomMode = 0 as *const OpusCustomMode;
1124    let mut bitrates: [i32; 256] = [0; 256];
1125    let mut bandLogE: [opus_val16; 42] = [0.; 42];
1126    let mut mem: *mut opus_val32 = NULL as *mut opus_val32;
1127    let mut preemph_mem: *mut opus_val32 = NULL as *mut opus_val32;
1128    let mut frame_size: i32 = 0;
1129    let mut rate_sum: i32 = 0;
1130    let mut smallest_packet: i32 = 0;
1131    if (*st).mapping_type as u32 == MAPPING_TYPE_SURROUND as i32 as u32 {
1132        preemph_mem = ms_get_preemph_mem(st);
1133        mem = ms_get_window_mem(st);
1134    }
1135    ptr = (st as *mut i8)
1136        .offset(align(::core::mem::size_of::<OpusMSEncoder>() as u64 as i32) as isize);
1137    opus_encoder_ctl!(
1138        ptr as *mut OpusEncoder,
1139        OPUS_GET_SAMPLE_RATE_REQUEST,
1140        &mut Fs
1141    );
1142    opus_encoder_ctl!(ptr as *mut OpusEncoder, OPUS_GET_VBR_REQUEST, &mut vbr);
1143    opus_encoder_ctl!(
1144        ptr as *mut OpusEncoder,
1145        CELT_GET_MODE_REQUEST,
1146        &mut celt_mode
1147    );
1148    frame_size = frame_size_select(analysis_frame_size, (*st).variable_duration, Fs);
1149    if frame_size <= 0 {
1150        return OPUS_BAD_ARG;
1151    }
1152    smallest_packet = (*st).layout.nb_streams * 2 - 1;
1153    if Fs / frame_size == 10 {
1154        smallest_packet += (*st).layout.nb_streams;
1155    }
1156    if max_data_bytes < smallest_packet {
1157        return OPUS_BUFFER_TOO_SMALL;
1158    }
1159    let vla = (2 * frame_size) as usize;
1160    let mut buf: Vec<opus_val16> = ::std::vec::from_elem(0., vla);
1161    coupled_size = opus_encoder_get_size(2);
1162    mono_size = opus_encoder_get_size(1);
1163    let vla_0 = (21 * (*st).layout.nb_channels) as usize;
1164    let mut bandSMR: Vec<opus_val16> = ::std::vec::from_elem(0., vla_0);
1165    if (*st).mapping_type as u32 == MAPPING_TYPE_SURROUND as i32 as u32 {
1166        surround_analysis(
1167            celt_mode,
1168            pcm,
1169            bandSMR.as_mut_ptr(),
1170            mem,
1171            preemph_mem,
1172            frame_size,
1173            120,
1174            (*st).layout.nb_channels,
1175            Fs,
1176            copy_channel_in,
1177            (*st).arch,
1178        );
1179    }
1180    rate_sum = rate_allocation(st, bitrates.as_mut_ptr(), frame_size);
1181    if vbr == 0 {
1182        if (*st).bitrate_bps == OPUS_AUTO {
1183            max_data_bytes = if max_data_bytes < 3 * rate_sum / (3 * 8 * Fs / frame_size) {
1184                max_data_bytes
1185            } else {
1186                3 * rate_sum / (3 * 8 * Fs / frame_size)
1187            };
1188        } else if (*st).bitrate_bps != OPUS_BITRATE_MAX {
1189            max_data_bytes = if max_data_bytes
1190                < (if smallest_packet > 3 * (*st).bitrate_bps / (3 * 8 * Fs / frame_size) {
1191                    smallest_packet
1192                } else {
1193                    3 * (*st).bitrate_bps / (3 * 8 * Fs / frame_size)
1194                }) {
1195                max_data_bytes
1196            } else if smallest_packet > 3 * (*st).bitrate_bps / (3 * 8 * Fs / frame_size) {
1197                smallest_packet
1198            } else {
1199                3 * (*st).bitrate_bps / (3 * 8 * Fs / frame_size)
1200            };
1201        }
1202    }
1203    ptr = (st as *mut i8)
1204        .offset(align(::core::mem::size_of::<OpusMSEncoder>() as u64 as i32) as isize);
1205    s = 0;
1206    while s < (*st).layout.nb_streams {
1207        let mut enc: *mut OpusEncoder = 0 as *mut OpusEncoder;
1208        enc = ptr as *mut OpusEncoder;
1209        if s < (*st).layout.nb_coupled_streams {
1210            ptr = ptr.offset(align(coupled_size) as isize);
1211        } else {
1212            ptr = ptr.offset(align(mono_size) as isize);
1213        }
1214        opus_encoder_ctl!(enc, OPUS_SET_BITRATE_REQUEST, bitrates[s as usize]);
1215        if (*st).mapping_type as u32 == MAPPING_TYPE_SURROUND as i32 as u32 {
1216            let mut equiv_rate: i32 = 0;
1217            equiv_rate = (*st).bitrate_bps;
1218            if (frame_size * 50) < Fs {
1219                equiv_rate -= 60 * (Fs / frame_size - 50) * (*st).layout.nb_channels;
1220            }
1221            if equiv_rate > 10000 * (*st).layout.nb_channels {
1222                opus_encoder_ctl!(enc, OPUS_SET_BANDWIDTH_REQUEST, 1105);
1223            } else if equiv_rate > 7000 * (*st).layout.nb_channels {
1224                opus_encoder_ctl!(enc, OPUS_SET_BANDWIDTH_REQUEST, 1104);
1225            } else if equiv_rate > 5000 * (*st).layout.nb_channels {
1226                opus_encoder_ctl!(enc, OPUS_SET_BANDWIDTH_REQUEST, 1103);
1227            } else {
1228                opus_encoder_ctl!(enc, OPUS_SET_BANDWIDTH_REQUEST, 1101);
1229            }
1230            if s < (*st).layout.nb_coupled_streams {
1231                opus_encoder_ctl!(enc, OPUS_SET_FORCE_MODE_REQUEST, 1002);
1232                opus_encoder_ctl!(enc, OPUS_SET_FORCE_CHANNELS_REQUEST, 2);
1233            }
1234        } else if (*st).mapping_type as u32 == MAPPING_TYPE_AMBISONICS as i32 as u32 {
1235            opus_encoder_ctl!(enc, OPUS_SET_FORCE_MODE_REQUEST, 1002);
1236        }
1237        s += 1;
1238    }
1239    ptr = (st as *mut i8)
1240        .offset(align(::core::mem::size_of::<OpusMSEncoder>() as u64 as i32) as isize);
1241    tot_size = 0;
1242    s = 0;
1243    while s < (*st).layout.nb_streams {
1244        let mut enc_0: *mut OpusEncoder = 0 as *mut OpusEncoder;
1245        let mut len: i32 = 0;
1246        let mut curr_max: i32 = 0;
1247        let mut c1: i32 = 0;
1248        let mut c2: i32 = 0;
1249        let mut ret: i32 = 0;
1250        opus_repacketizer_init(&mut rp);
1251        enc_0 = ptr as *mut OpusEncoder;
1252        if s < (*st).layout.nb_coupled_streams {
1253            let mut i: i32 = 0;
1254            let mut left: i32 = 0;
1255            let mut right: i32 = 0;
1256            left = get_left_channel(&mut (*st).layout, s, -1);
1257            right = get_right_channel(&mut (*st).layout, s, -1);
1258            (Some(copy_channel_in.expect("non-null function pointer")))
1259                .expect("non-null function pointer")(
1260                buf.as_mut_ptr(),
1261                2,
1262                pcm,
1263                (*st).layout.nb_channels,
1264                left,
1265                frame_size,
1266                user_data,
1267            );
1268            (Some(copy_channel_in.expect("non-null function pointer")))
1269                .expect("non-null function pointer")(
1270                buf.as_mut_ptr().offset(1 as isize),
1271                2,
1272                pcm,
1273                (*st).layout.nb_channels,
1274                right,
1275                frame_size,
1276                user_data,
1277            );
1278            ptr = ptr.offset(align(coupled_size) as isize);
1279            if (*st).mapping_type as u32 == MAPPING_TYPE_SURROUND as i32 as u32 {
1280                i = 0;
1281                while i < 21 {
1282                    bandLogE[i as usize] = *bandSMR.as_mut_ptr().offset((21 * left + i) as isize);
1283                    bandLogE[(21 + i) as usize] =
1284                        *bandSMR.as_mut_ptr().offset((21 * right + i) as isize);
1285                    i += 1;
1286                }
1287            }
1288            c1 = left;
1289            c2 = right;
1290        } else {
1291            let mut i_0: i32 = 0;
1292            let chan: i32 = get_mono_channel(&mut (*st).layout, s, -1);
1293            (Some(copy_channel_in.expect("non-null function pointer")))
1294                .expect("non-null function pointer")(
1295                buf.as_mut_ptr(),
1296                1,
1297                pcm,
1298                (*st).layout.nb_channels,
1299                chan,
1300                frame_size,
1301                user_data,
1302            );
1303            ptr = ptr.offset(align(mono_size) as isize);
1304            if (*st).mapping_type as u32 == MAPPING_TYPE_SURROUND as i32 as u32 {
1305                i_0 = 0;
1306                while i_0 < 21 {
1307                    bandLogE[i_0 as usize] =
1308                        *bandSMR.as_mut_ptr().offset((21 * chan + i_0) as isize);
1309                    i_0 += 1;
1310                }
1311            }
1312            c1 = chan;
1313            c2 = -1;
1314        }
1315        if (*st).mapping_type as u32 == MAPPING_TYPE_SURROUND as i32 as u32 {
1316            opus_encoder_ctl!(
1317                enc_0,
1318                OPUS_SET_ENERGY_MASK_REQUEST,
1319                bandLogE.as_mut_ptr().offset(
1320                    bandLogE.as_mut_ptr().offset_from(bandLogE.as_mut_ptr()) as i64 as isize,
1321                ),
1322            );
1323        }
1324        curr_max = max_data_bytes - tot_size;
1325        curr_max -= if 0 > 2 * ((*st).layout.nb_streams - s - 1) - 1 {
1326            0
1327        } else {
1328            2 * ((*st).layout.nb_streams - s - 1) - 1
1329        };
1330        if Fs / frame_size == 10 {
1331            curr_max -= (*st).layout.nb_streams - s - 1;
1332        }
1333        curr_max = if curr_max < 6 * 1275 + 12 {
1334            curr_max
1335        } else {
1336            6 * 1275 + 12
1337        };
1338        if s != (*st).layout.nb_streams - 1 {
1339            curr_max -= if curr_max > 253 { 2 } else { 1 };
1340        }
1341        if vbr == 0 && s == (*st).layout.nb_streams - 1 {
1342            opus_encoder_ctl!(
1343                enc_0,
1344                OPUS_SET_BITRATE_REQUEST,
1345                curr_max * (8 * Fs / frame_size),
1346            );
1347        }
1348        len = opus_encode_native(
1349            enc_0,
1350            buf.as_mut_ptr(),
1351            frame_size,
1352            tmp_data.as_mut_ptr(),
1353            curr_max,
1354            lsb_depth,
1355            pcm,
1356            analysis_frame_size,
1357            c1,
1358            c2,
1359            (*st).layout.nb_channels,
1360            downmix,
1361            float_api,
1362        );
1363        if len < 0 {
1364            return len;
1365        }
1366        ret = opus_repacketizer_cat(&mut rp, tmp_data.as_mut_ptr(), len);
1367        if ret != OPUS_OK {
1368            return OPUS_INTERNAL_ERROR;
1369        }
1370        len = opus_repacketizer_out_range_impl(
1371            &mut rp,
1372            0,
1373            opus_repacketizer_get_nb_frames(&mut rp),
1374            data,
1375            max_data_bytes - tot_size,
1376            (s != (*st).layout.nb_streams - 1) as i32,
1377            (vbr == 0 && s == (*st).layout.nb_streams - 1) as i32,
1378        );
1379        data = data.offset(len as isize);
1380        tot_size += len;
1381        s += 1;
1382    }
1383    return tot_size;
1384}
1385unsafe fn opus_copy_channel_in_float(
1386    dst: *mut opus_val16,
1387    dst_stride: i32,
1388    src: *const core::ffi::c_void,
1389    src_stride: i32,
1390    src_channel: i32,
1391    frame_size: i32,
1392    _user_data: *mut core::ffi::c_void,
1393) {
1394    let mut float_src: *const f32 = 0 as *const f32;
1395    let mut i: i32 = 0;
1396    float_src = src as *const f32;
1397    i = 0;
1398    while i < frame_size {
1399        *dst.offset((i * dst_stride) as isize) =
1400            *float_src.offset((i * src_stride + src_channel) as isize);
1401        i += 1;
1402    }
1403}
1404unsafe fn opus_copy_channel_in_short(
1405    dst: *mut opus_val16,
1406    dst_stride: i32,
1407    src: *const core::ffi::c_void,
1408    src_stride: i32,
1409    src_channel: i32,
1410    frame_size: i32,
1411    _user_data: *mut core::ffi::c_void,
1412) {
1413    let mut short_src: *const i16 = 0 as *const i16;
1414    let mut i: i32 = 0;
1415    short_src = src as *const i16;
1416    i = 0;
1417    while i < frame_size {
1418        *dst.offset((i * dst_stride) as isize) = 1 as f32 / 32768.0f32
1419            * *short_src.offset((i * src_stride + src_channel) as isize) as i32 as f32;
1420        i += 1;
1421    }
1422}
1423pub unsafe fn opus_multistream_encode_float(
1424    st: *mut OpusMSEncoder,
1425    pcm: *const opus_val16,
1426    frame_size: i32,
1427    data: *mut u8,
1428    max_data_bytes: i32,
1429) -> i32 {
1430    return opus_multistream_encode_native(
1431        st,
1432        Some(
1433            opus_copy_channel_in_float
1434                as unsafe fn(
1435                    *mut opus_val16,
1436                    i32,
1437                    *const core::ffi::c_void,
1438                    i32,
1439                    i32,
1440                    i32,
1441                    *mut core::ffi::c_void,
1442                ) -> (),
1443        ),
1444        pcm as *const core::ffi::c_void,
1445        frame_size,
1446        data,
1447        max_data_bytes,
1448        24,
1449        Some(
1450            downmix_float
1451                as unsafe fn(
1452                    *const core::ffi::c_void,
1453                    *mut opus_val32,
1454                    i32,
1455                    i32,
1456                    i32,
1457                    i32,
1458                    i32,
1459                ) -> (),
1460        ),
1461        1,
1462        NULL as *mut core::ffi::c_void,
1463    );
1464}
1465pub unsafe fn opus_multistream_encode(
1466    st: *mut OpusMSEncoder,
1467    pcm: *const i16,
1468    frame_size: i32,
1469    data: *mut u8,
1470    max_data_bytes: i32,
1471) -> i32 {
1472    return opus_multistream_encode_native(
1473        st,
1474        Some(
1475            opus_copy_channel_in_short
1476                as unsafe fn(
1477                    *mut opus_val16,
1478                    i32,
1479                    *const core::ffi::c_void,
1480                    i32,
1481                    i32,
1482                    i32,
1483                    *mut core::ffi::c_void,
1484                ) -> (),
1485        ),
1486        pcm as *const core::ffi::c_void,
1487        frame_size,
1488        data,
1489        max_data_bytes,
1490        16,
1491        Some(
1492            downmix_int
1493                as unsafe fn(
1494                    *const core::ffi::c_void,
1495                    *mut opus_val32,
1496                    i32,
1497                    i32,
1498                    i32,
1499                    i32,
1500                    i32,
1501                ) -> (),
1502        ),
1503        0,
1504        NULL as *mut core::ffi::c_void,
1505    );
1506}
1507pub unsafe fn opus_multistream_encoder_ctl_va_list(
1508    st: *mut OpusMSEncoder,
1509    request: i32,
1510    mut ap: VarArgs,
1511) -> i32 {
1512    let mut current_block: u64;
1513    let mut coupled_size: i32 = 0;
1514    let mut mono_size: i32 = 0;
1515    let mut ptr: *mut i8 = 0 as *mut i8;
1516    let mut ret: i32 = OPUS_OK;
1517    coupled_size = opus_encoder_get_size(2);
1518    mono_size = opus_encoder_get_size(1);
1519    ptr = (st as *mut i8)
1520        .offset(align(::core::mem::size_of::<OpusMSEncoder>() as u64 as i32) as isize);
1521    match request {
1522        OPUS_SET_BITRATE_REQUEST => {
1523            let mut value: i32 = ap.arg::<i32>();
1524            if value != OPUS_AUTO && value != OPUS_BITRATE_MAX {
1525                if value <= 0 {
1526                    current_block = 11382675479785311092;
1527                } else {
1528                    value = if 300000 * (*st).layout.nb_channels
1529                        < (if 500 * (*st).layout.nb_channels > value {
1530                            500 * (*st).layout.nb_channels
1531                        } else {
1532                            value
1533                        }) {
1534                        300000 * (*st).layout.nb_channels
1535                    } else if 500 * (*st).layout.nb_channels > value {
1536                        500 * (*st).layout.nb_channels
1537                    } else {
1538                        value
1539                    };
1540                    current_block = 10879442775620481940;
1541                }
1542            } else {
1543                current_block = 10879442775620481940;
1544            }
1545            match current_block {
1546                11382675479785311092 => {}
1547                _ => {
1548                    (*st).bitrate_bps = value;
1549                    current_block = 2616667235040759262;
1550                }
1551            }
1552        }
1553        OPUS_GET_BITRATE_REQUEST => {
1554            let mut s: i32 = 0;
1555            let value_0 = ap.arg::<&mut i32>();
1556            *value_0 = 0;
1557            s = 0;
1558            while s < (*st).layout.nb_streams {
1559                let mut rate: i32 = 0;
1560                let mut enc: *mut OpusEncoder = 0 as *mut OpusEncoder;
1561                enc = ptr as *mut OpusEncoder;
1562                if s < (*st).layout.nb_coupled_streams {
1563                    ptr = ptr.offset(align(coupled_size) as isize);
1564                } else {
1565                    ptr = ptr.offset(align(mono_size) as isize);
1566                }
1567                opus_encoder_ctl!(enc, request, &mut rate);
1568                *value_0 += rate;
1569                s += 1;
1570            }
1571            current_block = 2616667235040759262;
1572        }
1573        OPUS_GET_LSB_DEPTH_REQUEST
1574        | OPUS_GET_VBR_REQUEST
1575        | OPUS_GET_APPLICATION_REQUEST
1576        | OPUS_GET_BANDWIDTH_REQUEST
1577        | OPUS_GET_COMPLEXITY_REQUEST
1578        | OPUS_GET_PACKET_LOSS_PERC_REQUEST
1579        | OPUS_GET_DTX_REQUEST
1580        | OPUS_GET_VOICE_RATIO_REQUEST
1581        | OPUS_GET_VBR_CONSTRAINT_REQUEST
1582        | OPUS_GET_SIGNAL_REQUEST
1583        | OPUS_GET_LOOKAHEAD_REQUEST
1584        | OPUS_GET_SAMPLE_RATE_REQUEST
1585        | OPUS_GET_INBAND_FEC_REQUEST
1586        | OPUS_GET_FORCE_CHANNELS_REQUEST
1587        | OPUS_GET_PREDICTION_DISABLED_REQUEST
1588        | OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST => {
1589            let mut enc_0: *mut OpusEncoder = 0 as *mut OpusEncoder;
1590            let value_1 = ap.arg::<&mut i32>();
1591            enc_0 = ptr as *mut OpusEncoder;
1592            ret = opus_encoder_ctl!(enc_0, request, value_1);
1593            current_block = 2616667235040759262;
1594        }
1595        OPUS_GET_FINAL_RANGE_REQUEST => {
1596            let mut s_0: i32 = 0;
1597            let value_2 = ap.arg::<&mut u32>();
1598            let mut tmp: u32 = 0;
1599            *value_2 = 0;
1600            s_0 = 0;
1601            while s_0 < (*st).layout.nb_streams {
1602                let mut enc_1: *mut OpusEncoder = 0 as *mut OpusEncoder;
1603                enc_1 = ptr as *mut OpusEncoder;
1604                if s_0 < (*st).layout.nb_coupled_streams {
1605                    ptr = ptr.offset(align(coupled_size) as isize);
1606                } else {
1607                    ptr = ptr.offset(align(mono_size) as isize);
1608                }
1609                ret = opus_encoder_ctl!(enc_1, request, &mut tmp);
1610                if ret != OPUS_OK {
1611                    break;
1612                }
1613                *value_2 ^= tmp;
1614                s_0 += 1;
1615            }
1616            current_block = 2616667235040759262;
1617        }
1618        OPUS_SET_LSB_DEPTH_REQUEST
1619        | OPUS_SET_COMPLEXITY_REQUEST
1620        | OPUS_SET_VBR_REQUEST
1621        | OPUS_SET_VBR_CONSTRAINT_REQUEST
1622        | OPUS_SET_MAX_BANDWIDTH_REQUEST
1623        | OPUS_SET_BANDWIDTH_REQUEST
1624        | OPUS_SET_SIGNAL_REQUEST
1625        | OPUS_SET_APPLICATION_REQUEST
1626        | OPUS_SET_INBAND_FEC_REQUEST
1627        | OPUS_SET_PACKET_LOSS_PERC_REQUEST
1628        | OPUS_SET_DTX_REQUEST
1629        | OPUS_SET_FORCE_MODE_REQUEST
1630        | OPUS_SET_FORCE_CHANNELS_REQUEST
1631        | OPUS_SET_PREDICTION_DISABLED_REQUEST
1632        | OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST => {
1633            let mut s_1: i32 = 0;
1634            let value_3: i32 = ap.arg::<i32>();
1635            s_1 = 0;
1636            while s_1 < (*st).layout.nb_streams {
1637                let mut enc_2: *mut OpusEncoder = 0 as *mut OpusEncoder;
1638                enc_2 = ptr as *mut OpusEncoder;
1639                if s_1 < (*st).layout.nb_coupled_streams {
1640                    ptr = ptr.offset(align(coupled_size) as isize);
1641                } else {
1642                    ptr = ptr.offset(align(mono_size) as isize);
1643                }
1644                ret = opus_encoder_ctl!(enc_2, request, value_3);
1645                if ret != OPUS_OK {
1646                    break;
1647                }
1648                s_1 += 1;
1649            }
1650            current_block = 2616667235040759262;
1651        }
1652        OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST => {
1653            let mut s_2: i32 = 0;
1654            let mut stream_id: i32 = 0;
1655            let mut value_4: *mut *mut OpusEncoder = 0 as *mut *mut OpusEncoder;
1656            stream_id = ap.arg::<i32>();
1657            if stream_id < 0 || stream_id >= (*st).layout.nb_streams {
1658                current_block = 11382675479785311092;
1659            } else {
1660                value_4 = ap.arg::<&mut *mut OpusEncoder>();
1661                s_2 = 0;
1662                while s_2 < stream_id {
1663                    if s_2 < (*st).layout.nb_coupled_streams {
1664                        ptr = ptr.offset(align(coupled_size) as isize);
1665                    } else {
1666                        ptr = ptr.offset(align(mono_size) as isize);
1667                    }
1668                    s_2 += 1;
1669                }
1670                *value_4 = ptr as *mut OpusEncoder;
1671                current_block = 2616667235040759262;
1672            }
1673        }
1674        OPUS_SET_EXPERT_FRAME_DURATION_REQUEST => {
1675            let value_5: i32 = ap.arg::<i32>();
1676            (*st).variable_duration = value_5;
1677            current_block = 2616667235040759262;
1678        }
1679        OPUS_GET_EXPERT_FRAME_DURATION_REQUEST => {
1680            let value_6 = ap.arg::<&mut i32>();
1681            *value_6 = (*st).variable_duration;
1682            current_block = 2616667235040759262;
1683        }
1684        OPUS_RESET_STATE => {
1685            let mut s_3: i32 = 0;
1686            if (*st).mapping_type as u32 == MAPPING_TYPE_SURROUND as i32 as u32 {
1687                memset(
1688                    ms_get_preemph_mem(st) as *mut core::ffi::c_void,
1689                    0,
1690                    ((*st).layout.nb_channels as u64)
1691                        .wrapping_mul(::core::mem::size_of::<opus_val32>() as u64),
1692                );
1693                memset(
1694                    ms_get_window_mem(st) as *mut core::ffi::c_void,
1695                    0,
1696                    (((*st).layout.nb_channels * 120) as u64)
1697                        .wrapping_mul(::core::mem::size_of::<opus_val32>() as u64),
1698                );
1699            }
1700            s_3 = 0;
1701            while s_3 < (*st).layout.nb_streams {
1702                let mut enc_3: *mut OpusEncoder = 0 as *mut OpusEncoder;
1703                enc_3 = ptr as *mut OpusEncoder;
1704                if s_3 < (*st).layout.nb_coupled_streams {
1705                    ptr = ptr.offset(align(coupled_size) as isize);
1706                } else {
1707                    ptr = ptr.offset(align(mono_size) as isize);
1708                }
1709                ret = opus_encoder_ctl!(enc_3, OPUS_RESET_STATE);
1710                if ret != OPUS_OK {
1711                    break;
1712                }
1713                s_3 += 1;
1714            }
1715            current_block = 2616667235040759262;
1716        }
1717        _ => {
1718            ret = OPUS_UNIMPLEMENTED;
1719            current_block = 2616667235040759262;
1720        }
1721    }
1722    match current_block {
1723        2616667235040759262 => return ret,
1724        _ => return OPUS_BAD_ARG,
1725    };
1726}
1727pub unsafe fn opus_multistream_encoder_ctl_impl(
1728    st: *mut OpusMSEncoder,
1729    request: i32,
1730    args: VarArgs,
1731) -> i32 {
1732    let mut ret: i32 = 0;
1733    ret = opus_multistream_encoder_ctl_va_list(st, request, args);
1734    return ret;
1735}
1736#[macro_export]
1737macro_rules! opus_multistream_encoder_ctl {
1738    ($st:expr, $request:expr, $($arg:expr),*) => {
1739        $crate::opus_multistream_encoder_ctl_impl($st, $request, $crate::varargs!($($arg),*))
1740    };
1741    ($st:expr, $request:expr) => {
1742        opus_multistream_encoder_ctl!($st, $request,)
1743    };
1744    ($st:expr, $request:expr, $($arg:expr),*,) => {
1745        opus_multistream_encoder_ctl!($st, $request, $($arg),*)
1746    };
1747}
1748pub unsafe fn opus_multistream_encoder_destroy(st: *mut OpusMSEncoder) {
1749    free(st as *mut core::ffi::c_void);
1750}