diff --git a/src/bink.c b/src/bink.c index b414658..0164145 100644 --- a/src/bink.c +++ b/src/bink.c @@ -23,39 +23,44 @@ extern float PlatVolumeToGain(int volume); #define VIDEO_FRAMES 4 struct binkMovie { - AVFormatContext* avContext; - AVPacket packet; + uint timeStart; + BOOL looping; - int videoStreamIndex; - AVCodecContext* videoCodecContext; - AVFrame* videoFrame; - struct SwsContext* videoScaleContext; - int videoScaleLineSize[4]; - uint videoScaleWidth; - uint videoScaleHeight; - enum AVPixelFormat videoScaleFormat; + AVFormatContext* context; + AVPacket packet; + // 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]; int currentFrame; int renderedFrames; float frameDuration; + AVFrame* videoFrame; - int audioStreamIndex; - AVCodecContext* audioCodecContext; - AVFrame* audioFrame; - char* audioTempBuffer; + // Audio stream info. + int audioStream; + AVCodecContext* audioContext; + BOOL alInited; + ALuint alSource; + ALuint alNumChannels; + ALenum alFormat; + ALuint alSampleRate; - BOOL alInited; - ALuint alSource; - ALuint alBuffers[AUDIO_FRAMES]; - ALuint alFreeBuffers[AUDIO_FRAMES]; - ALuint alNumFreeBuffers; - ALuint alNumChannels; - ALenum alFormat; - ALuint alSampleRate; - - uint timeStart; - BOOL looping; + // Decoded audio frame queue. + ALuint audioFrames[AUDIO_FRAMES]; + ALuint alFreeBuffers[AUDIO_FRAMES]; + ALuint alNumFreeBuffers; + AVFrame* audioFrame; + char* audioTempBuffer; }; static int BinkRenderMovie(struct binkMovie* movie) @@ -72,7 +77,7 @@ static int BinkRenderMovie(struct binkMovie* movie) DrawAvpMenuBink(movie->videoFrames[movie->currentFrame%VIDEO_FRAMES][0], movie->videoFrame->width, movie->videoFrame->height, - movie->videoScaleLineSize[0]); + movie->scaleLineSize[0]); } return dt; } @@ -80,9 +85,9 @@ static int BinkRenderMovie(struct binkMovie* movie) static void BinkInitMovieStruct(struct binkMovie* aMovie) { *aMovie = (struct binkMovie){ - .audioStreamIndex = -1, - .videoStreamIndex = -1, - .videoScaleFormat = AV_PIX_FMT_NONE, + .audioStream = -1, + .videoStream = -1, + .scaleFormat = AV_PIX_FMT_NONE, }; } @@ -91,24 +96,24 @@ static void BinkReleaseMovie(struct binkMovie* aMovie) if (aMovie->alInited) { alSourceStop(aMovie->alSource); alDeleteSources(1, &aMovie->alSource); - alDeleteBuffers(AUDIO_FRAMES, aMovie->alBuffers); + alDeleteBuffers(AUDIO_FRAMES, aMovie->audioFrames); if (aMovie->audioTempBuffer) free(aMovie->audioTempBuffer); } - if (aMovie->avContext) - avformat_close_input(&aMovie->avContext); - if (aMovie->audioCodecContext) - avcodec_free_context(&aMovie->audioCodecContext); + if (aMovie->context) + avformat_close_input(&aMovie->context); + if (aMovie->audioContext) + avcodec_free_context(&aMovie->audioContext); if (aMovie->audioFrame) av_frame_free(&aMovie->audioFrame); - if (aMovie->videoCodecContext) - avcodec_free_context(&aMovie->videoCodecContext); + if (aMovie->videoContext) + avcodec_free_context(&aMovie->videoContext); if (aMovie->videoFrame) av_frame_free(&aMovie->videoFrame); - if (aMovie->videoScaleContext) { - sws_freeContext(aMovie->videoScaleContext); + if (aMovie->scaleContext) { + sws_freeContext(aMovie->scaleContext); for (int i = 0; i < VIDEO_FRAMES; i++) av_freep(&aMovie->videoFrames[i][0]); } @@ -119,37 +124,37 @@ static void BinkReleaseMovie(struct binkMovie* aMovie) static int DecodeVideoFrame(struct binkMovie* aMovie) { // Initialize scale context. - if (aMovie->videoScaleContext == NULL) { - if (aMovie->videoScaleWidth == 0) - aMovie->videoScaleWidth = aMovie->videoFrame->width; - if (aMovie->videoScaleHeight == 0) - aMovie->videoScaleHeight = aMovie->videoFrame->height; - if (aMovie->videoScaleFormat == AV_PIX_FMT_NONE) - aMovie->videoScaleFormat = AV_PIX_FMT_RGB565; + if (aMovie->scaleContext == NULL) { + if (aMovie->scaleWidth == 0) + aMovie->scaleWidth = aMovie->videoFrame->width; + if (aMovie->scaleHeight == 0) + aMovie->scaleHeight = aMovie->videoFrame->height; + if (aMovie->scaleFormat == AV_PIX_FMT_NONE) + aMovie->scaleFormat = AV_PIX_FMT_RGB565; - aMovie->videoScaleContext = sws_getContext( + aMovie->scaleContext = sws_getContext( aMovie->videoFrame->width, aMovie->videoFrame->height, aMovie->videoFrame->format, - aMovie->videoScaleWidth, aMovie->videoScaleHeight, - aMovie->videoScaleFormat, + aMovie->scaleWidth, aMovie->scaleHeight, + aMovie->scaleFormat, SWS_FAST_BILINEAR, NULL, NULL, NULL); - if (aMovie->videoScaleContext == NULL) + if (aMovie->scaleContext == NULL) return 0; for (int i = 0; i < VIDEO_FRAMES; i++) { av_image_alloc( - aMovie->videoFrames[i], aMovie->videoScaleLineSize, - aMovie->videoScaleWidth, aMovie->videoScaleHeight, - aMovie->videoScaleFormat, 1); + aMovie->videoFrames[i], aMovie->scaleLineSize, + aMovie->scaleWidth, aMovie->scaleHeight, + aMovie->scaleFormat, 1); } } - sws_scale(aMovie->videoScaleContext, + sws_scale(aMovie->scaleContext, (const uint8_t* const*)aMovie->videoFrame->data, aMovie->videoFrame->linesize, 0, aMovie->videoFrame->height, aMovie->videoFrames[(aMovie->currentFrame+aMovie->renderedFrames) % VIDEO_FRAMES], - aMovie->videoScaleLineSize); + aMovie->scaleLineSize); aMovie->renderedFrames++; return 1; } @@ -286,27 +291,27 @@ static int DecodeAudioFrame(struct binkMovie* aMovie) static int ReadPacket(struct binkMovie* aMovie) { // 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. if (aMovie->looping) { - av_seek_frame(aMovie->avContext, -1, 0, 0); + av_seek_frame(aMovie->context, -1, 0, 0); return ReadPacket(aMovie); } else { // Drain buffered frames. - if (aMovie->videoStreamIndex >= 0) - avcodec_send_packet(aMovie->videoCodecContext, NULL); - if (aMovie->audioStreamIndex >= 0) - avcodec_send_packet(aMovie->audioCodecContext, NULL); + if (aMovie->videoStream >= 0) + avcodec_send_packet(aMovie->videoContext, NULL); + if (aMovie->audioStream >= 0) + avcodec_send_packet(aMovie->audioContext, NULL); return 0; } } // Send the (possibly buffered) packet to decoder. int ret = AVERROR(EAGAIN); - if (aMovie->packet.stream_index == aMovie->videoStreamIndex) - ret = avcodec_send_packet(aMovie->videoCodecContext, &aMovie->packet); - else if (aMovie->packet.stream_index == aMovie->audioStreamIndex) - ret = avcodec_send_packet(aMovie->audioCodecContext, &aMovie->packet); + if (aMovie->packet.stream_index == aMovie->videoStream) + ret = avcodec_send_packet(aMovie->videoContext, &aMovie->packet); + else if (aMovie->packet.stream_index == aMovie->audioStream) + ret = avcodec_send_packet(aMovie->audioContext, &aMovie->packet); // Keep the packet around for next time if decoder’s buffer is full. if (ret == AVERROR(EAGAIN)) { @@ -324,22 +329,22 @@ static int BinkStartMovie(struct binkMovie* aMovie, const char* aFilename, aMovie->looping = aLoopFlag; if (aFmvFlag) { - aMovie->videoScaleWidth = 128; - aMovie->videoScaleHeight = 96; - aMovie->videoScaleFormat = AV_PIX_FMT_RGB24; + aMovie->scaleWidth = 128; + aMovie->scaleHeight = 96; + 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; - if (avformat_find_stream_info(aMovie->avContext, NULL) < 0) { + if (avformat_find_stream_info(aMovie->context, NULL) < 0) { BinkReleaseMovie(aMovie); return 0; } int numStreams = 0; - for (int i = 0; i < aMovie->avContext->nb_streams; i++) { - const AVStream* stream = aMovie->avContext->streams[i]; + for (int i = 0; i < aMovie->context->nb_streams; i++) { + const AVStream* stream = aMovie->context->streams[i]; const AVCodec* codec = avcodec_find_decoder(stream->codecpar->codec_id); if (!codec) continue; @@ -352,17 +357,17 @@ static int BinkStartMovie(struct binkMovie* aMovie, const char* aFilename, continue; } - if (aMovie->videoStreamIndex < 0 && context->codec_type == AVMEDIA_TYPE_VIDEO) { - aMovie->videoCodecContext = context; - aMovie->videoStreamIndex = i; + if (aMovie->videoStream < 0 && context->codec_type == AVMEDIA_TYPE_VIDEO) { + aMovie->videoContext = context; + aMovie->videoStream = i; aMovie->videoFrame = av_frame_alloc(); aMovie->frameDuration = 1000.0f * (float)stream->time_base.num / (float)stream->time_base.den; aMovie->timeStart = SDL_GetTicks(); numStreams++; - } else if (aMovie->audioStreamIndex < 0 && context->codec_type == AVMEDIA_TYPE_AUDIO) { - aMovie->audioCodecContext = context; - aMovie->audioStreamIndex = i; + } else if (aMovie->audioStream < 0 && context->codec_type == AVMEDIA_TYPE_AUDIO) { + aMovie->audioContext = context; + aMovie->audioStream = i; aMovie->audioFrame = av_frame_alloc(); 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_GAIN, 1.0); - alGenBuffers(AUDIO_FRAMES, aMovie->alBuffers); + alGenBuffers(AUDIO_FRAMES, aMovie->audioFrames); aMovie->alNumFreeBuffers = AUDIO_FRAMES; for (int i = 0; i < aMovie->alNumFreeBuffers; i++) - aMovie->alFreeBuffers[i] = aMovie->alBuffers[i]; + aMovie->alFreeBuffers[i] = aMovie->audioFrames[i]; numStreams++; } 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); return 0; } @@ -400,18 +405,18 @@ static int BinkStartMovie(struct binkMovie* aMovie, const char* aFilename, static int BinkUpdateMovie(struct binkMovie* aMovie) { - if(!aMovie->avContext) + if(!aMovie->context) return 0; const int eof = !ReadPacket(aMovie); int playing = 0; - if (aMovie->videoStreamIndex >= 0 && aMovie->renderedFrames < VIDEO_FRAMES) - if (avcodec_receive_frame(aMovie->videoCodecContext, aMovie->videoFrame) == 0) + if (aMovie->videoStream >= 0 && aMovie->renderedFrames < VIDEO_FRAMES) + if (avcodec_receive_frame(aMovie->videoContext, aMovie->videoFrame) == 0) playing += DecodeVideoFrame(aMovie); - if (aMovie->audioStreamIndex >= 0 && aMovie->alNumFreeBuffers > 0) - if (avcodec_receive_frame(aMovie->audioCodecContext, aMovie->audioFrame) == 0) + if (aMovie->audioStream >= 0 && aMovie->alNumFreeBuffers > 0) + if (avcodec_receive_frame(aMovie->audioContext, aMovie->audioFrame) == 0) playing += DecodeAudioFrame(aMovie); return eof && !playing ? -1 : playing; @@ -478,14 +483,14 @@ int PlayMusicBink(int volume) if (!SoundSys_IsOn()) return 1; - if (!musicMovie.avContext) + if (!musicMovie.context) return 1; - if (musicMovie.audioStreamIndex < 0 || !musicMovie.alInited) + if (musicMovie.audioStream < 0 || !musicMovie.alInited) return 1; 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; alGetSourcei(musicMovie.alSource, AL_BUFFERS_PROCESSED, &processedBuffers); if (processedBuffers + musicMovie.alNumFreeBuffers > 0) @@ -546,7 +551,7 @@ char* GetBinkFMVImage(FMVHandle aFmvHandle) return NULL; struct binkMovie* movie = (struct binkMovie*)aFmvHandle; - if (!movie->videoScaleContext) + if (!movie->scaleContext) return NULL; return movie->renderedFrames ? movie->videoFrames[movie->currentFrame%VIDEO_FRAMES][0] : NULL;