int FFmpegAudioDecoder::ReadCache(AudioBuffer<s16>& buffer, int count, int offset) { count = Math::Min((size_t)count, cacheLength / sizeof(AudioBuffer<s16>::AudioSample) / channels); buffer.DeinterlaceFrom((AudioBuffer<s16>::AudioSample*)cache, count, offset); cacheLength -= sizeof(AudioBuffer<s16>::AudioSample) * channels * count; memmove(cache, (u8*)cache + sizeof(AudioBuffer<s16>::AudioSample) * channels * count, cacheLength); return count; }
u32 FFmpegAudioDecoder::Read(AudioBuffer<s16>& buffer, u32 count, u32 boffset) { int offset = ReadCache(buffer, count, boffset); count -= offset; while (count > 0) { AVPacket originalPacket; if (!decoder->ReadPacket(&originalPacket, streamIndex)) break; AVPacket packet = originalPacket; cacheLength = 0; while (packet.size > 0) { int datasize = bufferSize; int used = avcodec_decode_audio3(stream->codec, (s16*)this->buffer, &datasize, &packet); if (used < 0) break; packet.size -= used; packet.data += used; if (datasize <= 0) break; int read = Math::Min((u32)datasize, count * 2 * channels); int left = datasize - read; if (read > 0) { int samples = read / sizeof(AudioBuffer<s16>::AudioSample) / channels; buffer.DeinterlaceFrom((AudioBuffer<s16>::AudioSample*)this->buffer, samples, boffset + offset); offset += samples; count -= samples; } if (left > 0) { memcpy((u8*)cache + cacheLength, (u8*)this->buffer + read, left); cacheLength += left; } } decoder->FreePacket(&originalPacket); } AudioCodec<s16>::Read(buffer, offset); return offset; }