Test mapped buffers in alffplay
This commit is contained in:
parent
b05592b0ab
commit
4ebb97bf73
@ -37,6 +37,25 @@ extern "C" {
|
|||||||
#include "AL/al.h"
|
#include "AL/al.h"
|
||||||
#include "AL/alext.h"
|
#include "AL/alext.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#ifndef AL_SOFT_map_buffer
|
||||||
|
#define AL_SOFT_map_buffer 1
|
||||||
|
typedef unsigned int ALbitfieldSOFT;
|
||||||
|
#define AL_MAP_READ_BIT_SOFT 0x01000000
|
||||||
|
#define AL_MAP_WRITE_BIT_SOFT 0x02000000
|
||||||
|
#define AL_PRESERVE_DATA_BIT_SOFT 0x04000000
|
||||||
|
#define AL_MAP_PERSISTENT_BIT_SOFT 0x08000000
|
||||||
|
typedef void* (AL_APIENTRY*LPALMAPBUFFERSOFT)(ALuint buffer, ALsizei offset, ALsizei length, ALbitfieldSOFT access);
|
||||||
|
typedef void (AL_APIENTRY*LPALUNMAPBUFFERSOFT)(ALuint buffer);
|
||||||
|
typedef void (AL_APIENTRY*LPALFLUSHMAPPEDBUFFERSOFT)(ALuint buffer, ALsizei offset, ALsizei length);
|
||||||
|
#ifdef AL_ALEXT_PROTOTYPES
|
||||||
|
AL_API void* AL_APIENTRY alMapBufferSOFT(ALuint buffer, ALsizei offset, ALsizei length, ALbitfieldSOFT access);
|
||||||
|
AL_API void AL_APIENTRY alUnmapBufferSOFT(ALuint buffer);
|
||||||
|
AL_API void AL_APIENTRY alFlushMappedBufferSOFT(ALuint buffer, ALsizei offset, ALsizei length);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using nanoseconds = std::chrono::nanoseconds;
|
using nanoseconds = std::chrono::nanoseconds;
|
||||||
@ -51,6 +70,9 @@ bool EnableDirectOut = false;
|
|||||||
LPALGETSOURCEI64VSOFT alGetSourcei64vSOFT;
|
LPALGETSOURCEI64VSOFT alGetSourcei64vSOFT;
|
||||||
LPALCGETINTEGER64VSOFT alcGetInteger64vSOFT;
|
LPALCGETINTEGER64VSOFT alcGetInteger64vSOFT;
|
||||||
|
|
||||||
|
LPALMAPBUFFERSOFT alMapBufferSOFT;
|
||||||
|
LPALUNMAPBUFFERSOFT alUnmapBufferSOFT;
|
||||||
|
|
||||||
const seconds AVNoSyncThreshold(10);
|
const seconds AVNoSyncThreshold(10);
|
||||||
|
|
||||||
const milliseconds VideoSyncThreshold(10);
|
const milliseconds VideoSyncThreshold(10);
|
||||||
@ -225,7 +247,7 @@ struct AudioState {
|
|||||||
|
|
||||||
int getSync();
|
int getSync();
|
||||||
int decodeFrame();
|
int decodeFrame();
|
||||||
int readAudio(uint8_t *samples, int length);
|
bool readAudio(uint8_t *samples, int length);
|
||||||
|
|
||||||
int handler();
|
int handler();
|
||||||
};
|
};
|
||||||
@ -564,7 +586,7 @@ static void sample_dup(uint8_t *out, const uint8_t *in, int count, int frame_siz
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int AudioState::readAudio(uint8_t *samples, int length)
|
bool AudioState::readAudio(uint8_t *samples, int length)
|
||||||
{
|
{
|
||||||
int sample_skip = getSync();
|
int sample_skip = getSync();
|
||||||
int audio_size = 0;
|
int audio_size = 0;
|
||||||
@ -619,8 +641,10 @@ int AudioState::readAudio(uint8_t *samples, int length)
|
|||||||
samples += rem*mFrameSize;
|
samples += rem*mFrameSize;
|
||||||
audio_size += rem;
|
audio_size += rem;
|
||||||
}
|
}
|
||||||
|
if(audio_size <= 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
if(audio_size < length && audio_size > 0)
|
if(audio_size < length)
|
||||||
{
|
{
|
||||||
int rem = length - audio_size;
|
int rem = length - audio_size;
|
||||||
std::fill_n(samples, rem*mFrameSize,
|
std::fill_n(samples, rem*mFrameSize,
|
||||||
@ -628,8 +652,7 @@ int AudioState::readAudio(uint8_t *samples, int length)
|
|||||||
mCurrentPts += nanoseconds(seconds(rem)) / mCodecCtx->sample_rate;
|
mCurrentPts += nanoseconds(seconds(rem)) / mCodecCtx->sample_rate;
|
||||||
audio_size += rem;
|
audio_size += rem;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
return audio_size * mFrameSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -743,9 +766,9 @@ int AudioState::handler()
|
|||||||
mFormat = AL_FORMAT_STEREO16;
|
mFormat = AL_FORMAT_STEREO16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void *samples = nullptr;
|
||||||
ALsizei buffer_len = std::chrono::duration_cast<std::chrono::duration<int>>(
|
ALsizei buffer_len = std::chrono::duration_cast<std::chrono::duration<int>>(
|
||||||
mCodecCtx->sample_rate * AudioBufferTime).count() * mFrameSize;
|
mCodecCtx->sample_rate * AudioBufferTime).count() * mFrameSize;
|
||||||
void *samples = av_malloc(buffer_len);
|
|
||||||
|
|
||||||
mSamples = NULL;
|
mSamples = NULL;
|
||||||
mSamplesMax = 0;
|
mSamplesMax = 0;
|
||||||
@ -779,6 +802,23 @@ int AudioState::handler()
|
|||||||
if(EnableDirectOut)
|
if(EnableDirectOut)
|
||||||
alSourcei(mSource, AL_DIRECT_CHANNELS_SOFT, AL_TRUE);
|
alSourcei(mSource, AL_DIRECT_CHANNELS_SOFT, AL_TRUE);
|
||||||
|
|
||||||
|
if(alGetError() != AL_NO_ERROR)
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
if(!alMapBufferSOFT)
|
||||||
|
samples = av_malloc(buffer_len);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(ALuint bufid : mBuffers)
|
||||||
|
alBufferData(bufid, mFormat | AL_MAP_WRITE_BIT_SOFT, nullptr, buffer_len,
|
||||||
|
mCodecCtx->sample_rate);
|
||||||
|
if(alGetError() != AL_NO_ERROR)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Failed to use mapped buffers\n");
|
||||||
|
samples = av_malloc(buffer_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while(alGetError() == AL_NO_ERROR && !mMovie.mQuit.load(std::memory_order_relaxed))
|
while(alGetError() == AL_NO_ERROR && !mMovie.mQuit.load(std::memory_order_relaxed))
|
||||||
{
|
{
|
||||||
/* First remove any processed buffers. */
|
/* First remove any processed buffers. */
|
||||||
@ -797,19 +837,25 @@ int AudioState::handler()
|
|||||||
alGetSourcei(mSource, AL_BUFFERS_QUEUED, &queued);
|
alGetSourcei(mSource, AL_BUFFERS_QUEUED, &queued);
|
||||||
while((ALuint)queued < mBuffers.size())
|
while((ALuint)queued < mBuffers.size())
|
||||||
{
|
{
|
||||||
int audio_size;
|
ALuint bufid = mBuffers[mBufferIdx];
|
||||||
|
|
||||||
/* Read the next chunk of data, fill the buffer, and queue it on
|
uint8_t *ptr = reinterpret_cast<uint8_t*>(
|
||||||
|
samples ? samples : alMapBufferSOFT(bufid, 0, buffer_len, AL_MAP_WRITE_BIT_SOFT)
|
||||||
|
);
|
||||||
|
if(!ptr) break;
|
||||||
|
|
||||||
|
/* Read the next chunk of data, filling the buffer, and queue it on
|
||||||
* the source */
|
* the source */
|
||||||
audio_size = readAudio(reinterpret_cast<uint8_t*>(samples), buffer_len);
|
bool got_audio = readAudio(ptr, buffer_len);
|
||||||
if(audio_size <= 0) break;
|
if(!samples) alUnmapBufferSOFT(bufid);
|
||||||
|
if(!got_audio) break;
|
||||||
|
|
||||||
ALuint bufid = mBuffers[mBufferIdx++];
|
if(samples)
|
||||||
mBufferIdx %= mBuffers.size();
|
alBufferData(bufid, mFormat, samples, buffer_len, mCodecCtx->sample_rate);
|
||||||
|
|
||||||
alBufferData(bufid, mFormat, samples, audio_size, mCodecCtx->sample_rate);
|
|
||||||
alSourceQueueBuffers(mSource, 1, &bufid);
|
alSourceQueueBuffers(mSource, 1, &bufid);
|
||||||
queued++;
|
mBufferIdx = (mBufferIdx+1) % mBuffers.size();
|
||||||
|
++queued;
|
||||||
}
|
}
|
||||||
if(queued == 0)
|
if(queued == 0)
|
||||||
break;
|
break;
|
||||||
@ -1590,6 +1636,14 @@ int main(int argc, char *argv[])
|
|||||||
alGetProcAddress("alGetSourcei64vSOFT")
|
alGetProcAddress("alGetSourcei64vSOFT")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if(alIsExtensionPresent("AL_SOFTX_map_buffer"))
|
||||||
|
{
|
||||||
|
std::cout<< "Found AL_SOFT_map_buffer" <<std::endl;
|
||||||
|
alMapBufferSOFT = reinterpret_cast<LPALMAPBUFFERSOFT>(
|
||||||
|
alGetProcAddress("alMapBufferSOFT"));
|
||||||
|
alUnmapBufferSOFT = reinterpret_cast<LPALUNMAPBUFFERSOFT>(
|
||||||
|
alGetProcAddress("alUnmapBufferSOFT"));
|
||||||
|
}
|
||||||
|
|
||||||
if(fileidx < argc && strcmp(argv[fileidx], "-direct") == 0)
|
if(fileidx < argc && strcmp(argv[fileidx], "-direct") == 0)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user