Bink: reorder and rename binkMovie fields
This commit is contained in:
parent
975c2cfdb9
commit
cb72993765
1 changed files with 94 additions and 89 deletions
183
src/bink.c
183
src/bink.c
|
@ -23,39 +23,44 @@ extern float PlatVolumeToGain(int volume);
|
||||||
#define VIDEO_FRAMES 4
|
#define VIDEO_FRAMES 4
|
||||||
|
|
||||||
struct binkMovie {
|
struct binkMovie {
|
||||||
AVFormatContext* avContext;
|
uint timeStart;
|
||||||
AVPacket packet;
|
BOOL looping;
|
||||||
|
|
||||||
int videoStreamIndex;
|
AVFormatContext* context;
|
||||||
AVCodecContext* videoCodecContext;
|
AVPacket packet;
|
||||||
AVFrame* videoFrame;
|
|
||||||
struct SwsContext* videoScaleContext;
|
|
||||||
int videoScaleLineSize[4];
|
|
||||||
uint videoScaleWidth;
|
|
||||||
uint videoScaleHeight;
|
|
||||||
enum AVPixelFormat videoScaleFormat;
|
|
||||||
|
|
||||||
|
// Video stream info.
|
||||||
|
int videoStream;
|
||||||
|
AVCodecContext* videoContext;
|
||||||
|
|
||||||
|
struct SwsContext* scaleContext;
|
||||||
|
enum AVPixelFormat scaleFormat;
|
||||||
|
int scaleLineSize[4];
|
||||||
|
uint scaleWidth;
|
||||||
|
uint scaleHeight;
|
||||||
|
|
||||||
|
// Decoded video frame queue.
|
||||||
uint8_t* videoFrames[VIDEO_FRAMES][4];
|
uint8_t* videoFrames[VIDEO_FRAMES][4];
|
||||||
int currentFrame;
|
int currentFrame;
|
||||||
int renderedFrames;
|
int renderedFrames;
|
||||||
float frameDuration;
|
float frameDuration;
|
||||||
|
AVFrame* videoFrame;
|
||||||
|
|
||||||
int audioStreamIndex;
|
// Audio stream info.
|
||||||
AVCodecContext* audioCodecContext;
|
int audioStream;
|
||||||
AVFrame* audioFrame;
|
AVCodecContext* audioContext;
|
||||||
char* audioTempBuffer;
|
BOOL alInited;
|
||||||
|
ALuint alSource;
|
||||||
|
ALuint alNumChannels;
|
||||||
|
ALenum alFormat;
|
||||||
|
ALuint alSampleRate;
|
||||||
|
|
||||||
BOOL alInited;
|
// Decoded audio frame queue.
|
||||||
ALuint alSource;
|
ALuint audioFrames[AUDIO_FRAMES];
|
||||||
ALuint alBuffers[AUDIO_FRAMES];
|
ALuint alFreeBuffers[AUDIO_FRAMES];
|
||||||
ALuint alFreeBuffers[AUDIO_FRAMES];
|
ALuint alNumFreeBuffers;
|
||||||
ALuint alNumFreeBuffers;
|
AVFrame* audioFrame;
|
||||||
ALuint alNumChannels;
|
char* audioTempBuffer;
|
||||||
ALenum alFormat;
|
|
||||||
ALuint alSampleRate;
|
|
||||||
|
|
||||||
uint timeStart;
|
|
||||||
BOOL looping;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int BinkRenderMovie(struct binkMovie* movie)
|
static int BinkRenderMovie(struct binkMovie* movie)
|
||||||
|
@ -72,7 +77,7 @@ static int BinkRenderMovie(struct binkMovie* movie)
|
||||||
DrawAvpMenuBink(movie->videoFrames[movie->currentFrame%VIDEO_FRAMES][0],
|
DrawAvpMenuBink(movie->videoFrames[movie->currentFrame%VIDEO_FRAMES][0],
|
||||||
movie->videoFrame->width,
|
movie->videoFrame->width,
|
||||||
movie->videoFrame->height,
|
movie->videoFrame->height,
|
||||||
movie->videoScaleLineSize[0]);
|
movie->scaleLineSize[0]);
|
||||||
}
|
}
|
||||||
return dt;
|
return dt;
|
||||||
}
|
}
|
||||||
|
@ -80,9 +85,9 @@ static int BinkRenderMovie(struct binkMovie* movie)
|
||||||
static void BinkInitMovieStruct(struct binkMovie* aMovie)
|
static void BinkInitMovieStruct(struct binkMovie* aMovie)
|
||||||
{
|
{
|
||||||
*aMovie = (struct binkMovie){
|
*aMovie = (struct binkMovie){
|
||||||
.audioStreamIndex = -1,
|
.audioStream = -1,
|
||||||
.videoStreamIndex = -1,
|
.videoStream = -1,
|
||||||
.videoScaleFormat = AV_PIX_FMT_NONE,
|
.scaleFormat = AV_PIX_FMT_NONE,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,24 +96,24 @@ static void BinkReleaseMovie(struct binkMovie* aMovie)
|
||||||
if (aMovie->alInited) {
|
if (aMovie->alInited) {
|
||||||
alSourceStop(aMovie->alSource);
|
alSourceStop(aMovie->alSource);
|
||||||
alDeleteSources(1, &aMovie->alSource);
|
alDeleteSources(1, &aMovie->alSource);
|
||||||
alDeleteBuffers(AUDIO_FRAMES, aMovie->alBuffers);
|
alDeleteBuffers(AUDIO_FRAMES, aMovie->audioFrames);
|
||||||
if (aMovie->audioTempBuffer)
|
if (aMovie->audioTempBuffer)
|
||||||
free(aMovie->audioTempBuffer);
|
free(aMovie->audioTempBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aMovie->avContext)
|
if (aMovie->context)
|
||||||
avformat_close_input(&aMovie->avContext);
|
avformat_close_input(&aMovie->context);
|
||||||
if (aMovie->audioCodecContext)
|
if (aMovie->audioContext)
|
||||||
avcodec_free_context(&aMovie->audioCodecContext);
|
avcodec_free_context(&aMovie->audioContext);
|
||||||
if (aMovie->audioFrame)
|
if (aMovie->audioFrame)
|
||||||
av_frame_free(&aMovie->audioFrame);
|
av_frame_free(&aMovie->audioFrame);
|
||||||
if (aMovie->videoCodecContext)
|
if (aMovie->videoContext)
|
||||||
avcodec_free_context(&aMovie->videoCodecContext);
|
avcodec_free_context(&aMovie->videoContext);
|
||||||
if (aMovie->videoFrame)
|
if (aMovie->videoFrame)
|
||||||
av_frame_free(&aMovie->videoFrame);
|
av_frame_free(&aMovie->videoFrame);
|
||||||
|
|
||||||
if (aMovie->videoScaleContext) {
|
if (aMovie->scaleContext) {
|
||||||
sws_freeContext(aMovie->videoScaleContext);
|
sws_freeContext(aMovie->scaleContext);
|
||||||
for (int i = 0; i < VIDEO_FRAMES; i++)
|
for (int i = 0; i < VIDEO_FRAMES; i++)
|
||||||
av_freep(&aMovie->videoFrames[i][0]);
|
av_freep(&aMovie->videoFrames[i][0]);
|
||||||
}
|
}
|
||||||
|
@ -119,37 +124,37 @@ static void BinkReleaseMovie(struct binkMovie* aMovie)
|
||||||
static int DecodeVideoFrame(struct binkMovie* aMovie)
|
static int DecodeVideoFrame(struct binkMovie* aMovie)
|
||||||
{
|
{
|
||||||
// Initialize scale context.
|
// Initialize scale context.
|
||||||
if (aMovie->videoScaleContext == NULL) {
|
if (aMovie->scaleContext == NULL) {
|
||||||
if (aMovie->videoScaleWidth == 0)
|
if (aMovie->scaleWidth == 0)
|
||||||
aMovie->videoScaleWidth = aMovie->videoFrame->width;
|
aMovie->scaleWidth = aMovie->videoFrame->width;
|
||||||
if (aMovie->videoScaleHeight == 0)
|
if (aMovie->scaleHeight == 0)
|
||||||
aMovie->videoScaleHeight = aMovie->videoFrame->height;
|
aMovie->scaleHeight = aMovie->videoFrame->height;
|
||||||
if (aMovie->videoScaleFormat == AV_PIX_FMT_NONE)
|
if (aMovie->scaleFormat == AV_PIX_FMT_NONE)
|
||||||
aMovie->videoScaleFormat = AV_PIX_FMT_RGB565;
|
aMovie->scaleFormat = AV_PIX_FMT_RGB565;
|
||||||
|
|
||||||
aMovie->videoScaleContext = sws_getContext(
|
aMovie->scaleContext = sws_getContext(
|
||||||
aMovie->videoFrame->width, aMovie->videoFrame->height,
|
aMovie->videoFrame->width, aMovie->videoFrame->height,
|
||||||
aMovie->videoFrame->format,
|
aMovie->videoFrame->format,
|
||||||
aMovie->videoScaleWidth, aMovie->videoScaleHeight,
|
aMovie->scaleWidth, aMovie->scaleHeight,
|
||||||
aMovie->videoScaleFormat,
|
aMovie->scaleFormat,
|
||||||
SWS_FAST_BILINEAR, NULL, NULL, NULL);
|
SWS_FAST_BILINEAR, NULL, NULL, NULL);
|
||||||
|
|
||||||
if (aMovie->videoScaleContext == NULL)
|
if (aMovie->scaleContext == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (int i = 0; i < VIDEO_FRAMES; i++) {
|
for (int i = 0; i < VIDEO_FRAMES; i++) {
|
||||||
av_image_alloc(
|
av_image_alloc(
|
||||||
aMovie->videoFrames[i], aMovie->videoScaleLineSize,
|
aMovie->videoFrames[i], aMovie->scaleLineSize,
|
||||||
aMovie->videoScaleWidth, aMovie->videoScaleHeight,
|
aMovie->scaleWidth, aMovie->scaleHeight,
|
||||||
aMovie->videoScaleFormat, 1);
|
aMovie->scaleFormat, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sws_scale(aMovie->videoScaleContext,
|
sws_scale(aMovie->scaleContext,
|
||||||
(const uint8_t* const*)aMovie->videoFrame->data,
|
(const uint8_t* const*)aMovie->videoFrame->data,
|
||||||
aMovie->videoFrame->linesize, 0, aMovie->videoFrame->height,
|
aMovie->videoFrame->linesize, 0, aMovie->videoFrame->height,
|
||||||
aMovie->videoFrames[(aMovie->currentFrame+aMovie->renderedFrames) % VIDEO_FRAMES],
|
aMovie->videoFrames[(aMovie->currentFrame+aMovie->renderedFrames) % VIDEO_FRAMES],
|
||||||
aMovie->videoScaleLineSize);
|
aMovie->scaleLineSize);
|
||||||
aMovie->renderedFrames++;
|
aMovie->renderedFrames++;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -286,27 +291,27 @@ static int DecodeAudioFrame(struct binkMovie* aMovie)
|
||||||
static int ReadPacket(struct binkMovie* aMovie)
|
static int ReadPacket(struct binkMovie* aMovie)
|
||||||
{
|
{
|
||||||
// Read from file if no packet is buffered.
|
// Read from file if no packet is buffered.
|
||||||
if (!aMovie->packet.buf && av_read_frame(aMovie->avContext, &aMovie->packet) < 0) {
|
if (!aMovie->packet.buf && av_read_frame(aMovie->context, &aMovie->packet) < 0) {
|
||||||
// No more packets in file.
|
// No more packets in file.
|
||||||
if (aMovie->looping) {
|
if (aMovie->looping) {
|
||||||
av_seek_frame(aMovie->avContext, -1, 0, 0);
|
av_seek_frame(aMovie->context, -1, 0, 0);
|
||||||
return ReadPacket(aMovie);
|
return ReadPacket(aMovie);
|
||||||
} else {
|
} else {
|
||||||
// Drain buffered frames.
|
// Drain buffered frames.
|
||||||
if (aMovie->videoStreamIndex >= 0)
|
if (aMovie->videoStream >= 0)
|
||||||
avcodec_send_packet(aMovie->videoCodecContext, NULL);
|
avcodec_send_packet(aMovie->videoContext, NULL);
|
||||||
if (aMovie->audioStreamIndex >= 0)
|
if (aMovie->audioStream >= 0)
|
||||||
avcodec_send_packet(aMovie->audioCodecContext, NULL);
|
avcodec_send_packet(aMovie->audioContext, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the (possibly buffered) packet to decoder.
|
// Send the (possibly buffered) packet to decoder.
|
||||||
int ret = AVERROR(EAGAIN);
|
int ret = AVERROR(EAGAIN);
|
||||||
if (aMovie->packet.stream_index == aMovie->videoStreamIndex)
|
if (aMovie->packet.stream_index == aMovie->videoStream)
|
||||||
ret = avcodec_send_packet(aMovie->videoCodecContext, &aMovie->packet);
|
ret = avcodec_send_packet(aMovie->videoContext, &aMovie->packet);
|
||||||
else if (aMovie->packet.stream_index == aMovie->audioStreamIndex)
|
else if (aMovie->packet.stream_index == aMovie->audioStream)
|
||||||
ret = avcodec_send_packet(aMovie->audioCodecContext, &aMovie->packet);
|
ret = avcodec_send_packet(aMovie->audioContext, &aMovie->packet);
|
||||||
|
|
||||||
// Keep the packet around for next time if decoder’s buffer is full.
|
// Keep the packet around for next time if decoder’s buffer is full.
|
||||||
if (ret == AVERROR(EAGAIN)) {
|
if (ret == AVERROR(EAGAIN)) {
|
||||||
|
@ -324,22 +329,22 @@ static int BinkStartMovie(struct binkMovie* aMovie, const char* aFilename,
|
||||||
aMovie->looping = aLoopFlag;
|
aMovie->looping = aLoopFlag;
|
||||||
|
|
||||||
if (aFmvFlag) {
|
if (aFmvFlag) {
|
||||||
aMovie->videoScaleWidth = 128;
|
aMovie->scaleWidth = 128;
|
||||||
aMovie->videoScaleHeight = 96;
|
aMovie->scaleHeight = 96;
|
||||||
aMovie->videoScaleFormat = AV_PIX_FMT_RGB24;
|
aMovie->scaleFormat = AV_PIX_FMT_RGB24;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (avformat_open_input(&aMovie->avContext, aFilename, NULL, NULL) != 0)
|
if (avformat_open_input(&aMovie->context, aFilename, NULL, NULL) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (avformat_find_stream_info(aMovie->avContext, NULL) < 0) {
|
if (avformat_find_stream_info(aMovie->context, NULL) < 0) {
|
||||||
BinkReleaseMovie(aMovie);
|
BinkReleaseMovie(aMovie);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int numStreams = 0;
|
int numStreams = 0;
|
||||||
for (int i = 0; i < aMovie->avContext->nb_streams; i++) {
|
for (int i = 0; i < aMovie->context->nb_streams; i++) {
|
||||||
const AVStream* stream = aMovie->avContext->streams[i];
|
const AVStream* stream = aMovie->context->streams[i];
|
||||||
const AVCodec* codec = avcodec_find_decoder(stream->codecpar->codec_id);
|
const AVCodec* codec = avcodec_find_decoder(stream->codecpar->codec_id);
|
||||||
if (!codec)
|
if (!codec)
|
||||||
continue;
|
continue;
|
||||||
|
@ -352,17 +357,17 @@ static int BinkStartMovie(struct binkMovie* aMovie, const char* aFilename,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aMovie->videoStreamIndex < 0 && context->codec_type == AVMEDIA_TYPE_VIDEO) {
|
if (aMovie->videoStream < 0 && context->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||||
aMovie->videoCodecContext = context;
|
aMovie->videoContext = context;
|
||||||
aMovie->videoStreamIndex = i;
|
aMovie->videoStream = i;
|
||||||
aMovie->videoFrame = av_frame_alloc();
|
aMovie->videoFrame = av_frame_alloc();
|
||||||
aMovie->frameDuration =
|
aMovie->frameDuration =
|
||||||
1000.0f * (float)stream->time_base.num / (float)stream->time_base.den;
|
1000.0f * (float)stream->time_base.num / (float)stream->time_base.den;
|
||||||
aMovie->timeStart = SDL_GetTicks();
|
aMovie->timeStart = SDL_GetTicks();
|
||||||
numStreams++;
|
numStreams++;
|
||||||
} else if (aMovie->audioStreamIndex < 0 && context->codec_type == AVMEDIA_TYPE_AUDIO) {
|
} else if (aMovie->audioStream < 0 && context->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||||
aMovie->audioCodecContext = context;
|
aMovie->audioContext = context;
|
||||||
aMovie->audioStreamIndex = i;
|
aMovie->audioStream = i;
|
||||||
aMovie->audioFrame = av_frame_alloc();
|
aMovie->audioFrame = av_frame_alloc();
|
||||||
|
|
||||||
alGenSources(1, &aMovie->alSource);
|
alGenSources(1, &aMovie->alSource);
|
||||||
|
@ -374,10 +379,10 @@ static int BinkStartMovie(struct binkMovie* aMovie, const char* aFilename,
|
||||||
alSourcef(aMovie->alSource, AL_PITCH, 1.0);
|
alSourcef(aMovie->alSource, AL_PITCH, 1.0);
|
||||||
alSourcef(aMovie->alSource, AL_GAIN, 1.0);
|
alSourcef(aMovie->alSource, AL_GAIN, 1.0);
|
||||||
|
|
||||||
alGenBuffers(AUDIO_FRAMES, aMovie->alBuffers);
|
alGenBuffers(AUDIO_FRAMES, aMovie->audioFrames);
|
||||||
aMovie->alNumFreeBuffers = AUDIO_FRAMES;
|
aMovie->alNumFreeBuffers = AUDIO_FRAMES;
|
||||||
for (int i = 0; i < aMovie->alNumFreeBuffers; i++)
|
for (int i = 0; i < aMovie->alNumFreeBuffers; i++)
|
||||||
aMovie->alFreeBuffers[i] = aMovie->alBuffers[i];
|
aMovie->alFreeBuffers[i] = aMovie->audioFrames[i];
|
||||||
|
|
||||||
numStreams++;
|
numStreams++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -385,7 +390,7 @@ static int BinkStartMovie(struct binkMovie* aMovie, const char* aFilename,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aMovie->videoStreamIndex < 0 && aMovie->audioStreamIndex < 0) {
|
if (aMovie->videoStream < 0 && aMovie->audioStream < 0) {
|
||||||
BinkReleaseMovie(aMovie);
|
BinkReleaseMovie(aMovie);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -400,18 +405,18 @@ static int BinkStartMovie(struct binkMovie* aMovie, const char* aFilename,
|
||||||
|
|
||||||
static int BinkUpdateMovie(struct binkMovie* aMovie)
|
static int BinkUpdateMovie(struct binkMovie* aMovie)
|
||||||
{
|
{
|
||||||
if(!aMovie->avContext)
|
if(!aMovie->context)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
const int eof = !ReadPacket(aMovie);
|
const int eof = !ReadPacket(aMovie);
|
||||||
|
|
||||||
int playing = 0;
|
int playing = 0;
|
||||||
if (aMovie->videoStreamIndex >= 0 && aMovie->renderedFrames < VIDEO_FRAMES)
|
if (aMovie->videoStream >= 0 && aMovie->renderedFrames < VIDEO_FRAMES)
|
||||||
if (avcodec_receive_frame(aMovie->videoCodecContext, aMovie->videoFrame) == 0)
|
if (avcodec_receive_frame(aMovie->videoContext, aMovie->videoFrame) == 0)
|
||||||
playing += DecodeVideoFrame(aMovie);
|
playing += DecodeVideoFrame(aMovie);
|
||||||
|
|
||||||
if (aMovie->audioStreamIndex >= 0 && aMovie->alNumFreeBuffers > 0)
|
if (aMovie->audioStream >= 0 && aMovie->alNumFreeBuffers > 0)
|
||||||
if (avcodec_receive_frame(aMovie->audioCodecContext, aMovie->audioFrame) == 0)
|
if (avcodec_receive_frame(aMovie->audioContext, aMovie->audioFrame) == 0)
|
||||||
playing += DecodeAudioFrame(aMovie);
|
playing += DecodeAudioFrame(aMovie);
|
||||||
|
|
||||||
return eof && !playing ? -1 : playing;
|
return eof && !playing ? -1 : playing;
|
||||||
|
@ -478,14 +483,14 @@ int PlayMusicBink(int volume)
|
||||||
if (!SoundSys_IsOn())
|
if (!SoundSys_IsOn())
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (!musicMovie.avContext)
|
if (!musicMovie.context)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (musicMovie.audioStreamIndex < 0 || !musicMovie.alInited)
|
if (musicMovie.audioStream < 0 || !musicMovie.alInited)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
alSourcef(musicMovie.alSource, AL_GAIN, PlatVolumeToGain(volume));
|
alSourcef(musicMovie.alSource, AL_GAIN, PlatVolumeToGain(volume));
|
||||||
for (int i = 0; i < musicMovie.avContext->nb_streams * AUDIO_FRAMES; i++) {
|
for (int i = 0; i < musicMovie.context->nb_streams * AUDIO_FRAMES; i++) {
|
||||||
int processedBuffers = 0;
|
int processedBuffers = 0;
|
||||||
alGetSourcei(musicMovie.alSource, AL_BUFFERS_PROCESSED, &processedBuffers);
|
alGetSourcei(musicMovie.alSource, AL_BUFFERS_PROCESSED, &processedBuffers);
|
||||||
if (processedBuffers + musicMovie.alNumFreeBuffers > 0)
|
if (processedBuffers + musicMovie.alNumFreeBuffers > 0)
|
||||||
|
@ -546,7 +551,7 @@ char* GetBinkFMVImage(FMVHandle aFmvHandle)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
struct binkMovie* movie = (struct binkMovie*)aFmvHandle;
|
struct binkMovie* movie = (struct binkMovie*)aFmvHandle;
|
||||||
if (!movie->videoScaleContext)
|
if (!movie->scaleContext)
|
||||||
return NULL;
|
return NULL;
|
||||||
return movie->renderedFrames ?
|
return movie->renderedFrames ?
|
||||||
movie->videoFrames[movie->currentFrame%VIDEO_FRAMES][0] : NULL;
|
movie->videoFrames[movie->currentFrame%VIDEO_FRAMES][0] : NULL;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue