예제 #1
0
        public int Read(int count)
        {
            int offset = ReadCache(count, 0);

            while (count - offset > 0)
            {
                if (FFmpeg.av_read_frame(FormatPointer, PacketPointer) < 0)
                {
                    break;
                }
                FFmpeg.AVPacket packet = (FFmpeg.AVPacket)Marshal.PtrToStructure(PacketPointer, typeof(FFmpeg.AVPacket));

                Cache.Position = 0;
                CacheOffset    = 0;
                CacheLength    = 0;

                while (packet.size > 0)
                {
                    int datasize = FFmpegBufferSize;
                    int used     = FFmpeg.avcodec_decode_audio2(AVStream.codec, FFmpegBuffer, ref datasize, packet.data, packet.size);
                    packet.size -= used;
                    packet.data  = new IntPtr(packet.data.ToInt32() + used);

                    if (datasize <= 0)
                    {
                        break;
                    }

                    int read = Math.Max(Math.Min(datasize, (count - offset) * 2 * Channels), 0);
                    int left = datasize - read;
                    if (read > 0)
                    {
                        int     samples   = read / 2 / Channels;
                        short[] bitstream = new short[read / 2];
                        Marshal.Copy(FFmpegBuffer, bitstream, 0, read / 2);
                        AudioBuffer.DeinterlaceFrom(bitstream, samples, offset);
                        offset += samples;
                    }

                    if (left > 0)
                    {
                        Marshal.Copy(new IntPtr(FFmpegBuffer.ToInt32() + read), CacheBuffer, 0, left);
                        Cache.Write(CacheBuffer, read, left);
                        CacheLength += left;
                    }
                }
            }

            return(offset);
        }
예제 #2
0
        private int ReadCache(int count, int offset)
        {
            Cache.Position = CacheOffset;
            int bytesize = Math.Min((count - offset) * 2 * Channels, CacheLength - CacheOffset);

            if (bytesize <= 0)
            {
                return(offset);
            }
            short[] bitstream = new short[bytesize / 2];
            int     samples   = bytesize / 2 / Channels;

            Buffer.BlockCopy(Cache.GetBuffer(), CacheOffset, bitstream, 0, bytesize);
            AudioBuffer.DeinterlaceFrom(bitstream, samples, offset);
            offset      += samples;
            CacheOffset += bytesize;
            return(offset);
        }