コード例 #1
0
        internal int opus_repacketizer_cat_impl(byte[] data, int data_ptr, int len, int self_delimited)
        {
            byte dummy_toc;
            int  dummy_offset;
            int  curr_nb_frames, ret;

            /* Set of check ToC */
            if (len < 1)
            {
                return(OpusError.OPUS_INVALID_PACKET);
            }

            if (this.nb_frames == 0)
            {
                this.toc       = data[data_ptr];
                this.framesize = OpusPacketInfo.GetNumSamplesPerFrame(data, data_ptr, 8000);
            }
            else if ((this.toc & 0xFC) != (data[data_ptr] & 0xFC))
            {
                /*fprintf(stderr, "toc mismatch: 0x%x vs 0x%x\n", rp.toc, data[0]);*/
                return(OpusError.OPUS_INVALID_PACKET);
            }
            curr_nb_frames = OpusPacketInfo.GetNumFrames(data, data_ptr, len);
            if (curr_nb_frames < 1)
            {
                return(OpusError.OPUS_INVALID_PACKET);
            }

            /* Check the 120 ms maximum packet size */
            if ((curr_nb_frames + this.nb_frames) * this.framesize > 960)
            {
                return(OpusError.OPUS_INVALID_PACKET);
            }

            ret = OpusPacketInfo.opus_packet_parse_impl(data, data_ptr, len, self_delimited, out dummy_toc, this.frames, this.frames_ptrs, this.nb_frames, this.len, this.nb_frames, out dummy_offset, out dummy_offset);
            if (ret < 1)
            {
                return(ret);
            }

            this.nb_frames += curr_nb_frames;
            return(OpusError.OPUS_OK);
        }
コード例 #2
0
        internal int opus_decode_native(byte[] data, int data_ptr,
                                        int len, short[] pcm_out, int pcm_out_ptr, int frame_size, int decode_fec,
                                        int self_delimited, out int packet_offset, int soft_clip)
        {
            int  i, nb_samples;
            int  count, offset;
            byte toc;
            int  packet_frame_size, packet_stream_channels;

            packet_offset = 0;
            OpusBandwidth packet_bandwidth;
            OpusMode      packet_mode;

            /* 48 x 2.5 ms = 120 ms */
            // fixme: make sure these values can fit in an int16
            short[] size = new short[48];
            if (decode_fec < 0 || decode_fec > 1)
            {
                return(OpusError.OPUS_BAD_ARG);
            }
            /* For FEC/PLC, frame_size has to be to have a multiple of 2.5 ms */
            if ((decode_fec != 0 || len == 0 || data == null) && frame_size % (this.Fs / 400) != 0)
            {
                return(OpusError.OPUS_BAD_ARG);
            }
            if (len == 0 || data == null)
            {
                int pcm_count = 0;
                do
                {
                    int ret;
                    ret = opus_decode_frame(null, 0, 0, pcm_out, pcm_out_ptr + (pcm_count * this.channels), frame_size - pcm_count, 0);
                    if (ret < 0)
                    {
                        return(ret);
                    }
                    pcm_count += ret;
                } while (pcm_count < frame_size);
                Inlines.OpusAssert(pcm_count == frame_size);
                this.last_packet_duration = pcm_count;
                return(pcm_count);
            }
            else if (len < 0)
            {
                return(OpusError.OPUS_BAD_ARG);
            }

            packet_mode            = OpusPacketInfo.GetEncoderMode(data, data_ptr);
            packet_bandwidth       = OpusPacketInfo.GetBandwidth(data, data_ptr);
            packet_frame_size      = OpusPacketInfo.GetNumSamplesPerFrame(data, data_ptr, this.Fs);
            packet_stream_channels = OpusPacketInfo.GetNumEncodedChannels(data, data_ptr);

            count = OpusPacketInfo.opus_packet_parse_impl(data, data_ptr, len, self_delimited, out toc, null, null, 0,
                                                          size, 0, out offset, out packet_offset);

            if (count < 0)
            {
                return(count);
            }

            data_ptr += offset;

            if (decode_fec != 0)
            {
                int dummy;
                int duration_copy;
                int ret;
                /* If no FEC can be present, run the PLC (recursive call) */
                if (frame_size < packet_frame_size || packet_mode == OpusMode.MODE_CELT_ONLY || this.mode == OpusMode.MODE_CELT_ONLY)
                {
                    return(opus_decode_native(null, 0, 0, pcm_out, pcm_out_ptr, frame_size, 0, 0, out dummy, soft_clip));
                }
                /* Otherwise, run the PLC on everything except the size for which we might have FEC */
                duration_copy = this.last_packet_duration;
                if (frame_size - packet_frame_size != 0)
                {
                    ret = opus_decode_native(null, 0, 0, pcm_out, pcm_out_ptr, frame_size - packet_frame_size, 0, 0, out dummy, soft_clip);
                    if (ret < 0)
                    {
                        this.last_packet_duration = duration_copy;
                        return(ret);
                    }
                    Inlines.OpusAssert(ret == frame_size - packet_frame_size);
                }
                /* Complete with FEC */
                this.mode            = packet_mode;
                this.bandwidth       = packet_bandwidth;
                this.frame_size      = packet_frame_size;
                this.stream_channels = packet_stream_channels;
                ret = opus_decode_frame(data, data_ptr, size[0], pcm_out, pcm_out_ptr + (this.channels * (frame_size - packet_frame_size)),
                                        packet_frame_size, 1);
                if (ret < 0)
                {
                    return(ret);
                }
                else
                {
                    this.last_packet_duration = frame_size;
                    return(frame_size);
                }
            }

            if (count * packet_frame_size > frame_size)
            {
                return(OpusError.OPUS_BUFFER_TOO_SMALL);
            }

            /* Update the state as the last step to avoid updating it on an invalid packet */
            this.mode            = packet_mode;
            this.bandwidth       = packet_bandwidth;
            this.frame_size      = packet_frame_size;
            this.stream_channels = packet_stream_channels;

            nb_samples = 0;
            for (i = 0; i < count; i++)
            {
                int ret;
                ret = opus_decode_frame(data, data_ptr, size[i], pcm_out, pcm_out_ptr + (nb_samples * this.channels), frame_size - nb_samples, 0);
                if (ret < 0)
                {
                    return(ret);
                }
                Inlines.OpusAssert(ret == packet_frame_size);
                data_ptr   += size[i];
                nb_samples += ret;
            }
            this.last_packet_duration = nb_samples;

            return(nb_samples);
        }