diff --git a/README.MD b/README.MD index 105fac9..d9423aa 100644 --- a/README.MD +++ b/README.MD @@ -2,16 +2,17 @@ FFMPEG Media Plugin for unreal engine =================================== A plugin that let's you use the FFMPEG library as media player +WARNING: Video not work if DisableAudio = false. ## Features: - - Works on Windows and Mac + - Works on Windows, Linux and Mac - Support for hardware accelerated codecs - Support for videos with alpha ## How to use -1. The plugin works with Unreal 4.26 +1. The plugin works with Unreal 5.4 2. You can clone the repository to `/Plugins/` or if you want you can use git submodules to your own git repository. Alternatively, you can copy to the `Engine/Plugins/` if you wish to make the plugin available to all of your projects. > Do not forget to run UE4's `Generate Project Files` to account for these changes! 3. Follow the steps to [play a video tutorial](https://docs.unrealengine.com/en-us/Engine/MediaFramework/HowTo/FileMediaSource) but insead of using the automatic player, choose the FFMPEGPlayer inside the players overrides for the step 5. diff --git a/Source/FFMPEGMedia/Private/FFMPEG/FFMPEGDecoder.cpp b/Source/FFMPEGMedia/Private/FFMPEG/FFMPEGDecoder.cpp index 5f3708f..8a70152 100644 --- a/Source/FFMPEGMedia/Private/FFMPEG/FFMPEGDecoder.cpp +++ b/Source/FFMPEGMedia/Private/FFMPEG/FFMPEGDecoder.cpp @@ -148,8 +148,6 @@ int FFMPEGDecoder::DecodeFrame(AVFrame* frame, AVSubtitle* sub) av_packet_unref(&pkt); } } - - return ret; } void FFMPEGDecoder::SetDecoderReorderPts(int pts) diff --git a/Source/FFMPEGMedia/Private/Player/FFMPEGMediaAudioSample.h b/Source/FFMPEGMedia/Private/Player/FFMPEGMediaAudioSample.h index ac82dd7..3020538 100644 --- a/Source/FFMPEGMedia/Private/Player/FFMPEGMediaAudioSample.h +++ b/Source/FFMPEGMedia/Private/Player/FFMPEGMediaAudioSample.h @@ -61,7 +61,7 @@ class FFFMPEGMediaAudioSample Channels = InChannels; Duration = InDuration; SampleRate = InSampleRate; - Time = InTime; + Time.Time = InTime; return true; } diff --git a/Source/FFMPEGMedia/Private/Player/FFMPEGMediaBinarySample.h b/Source/FFMPEGMedia/Private/Player/FFMPEGMediaBinarySample.h index b2dc01c..31e6b89 100644 --- a/Source/FFMPEGMedia/Private/Player/FFMPEGMediaBinarySample.h +++ b/Source/FFMPEGMedia/Private/Player/FFMPEGMediaBinarySample.h @@ -52,7 +52,7 @@ class FFFMPEGMediaBinarySample Buffer.Append((uint8*)InBuffer, InSize); Duration = InDuration; - Time = InTime; + Time.Time = InTime; return true; } diff --git a/Source/FFMPEGMedia/Private/Player/FFMPEGMediaOverlaySample.h b/Source/FFMPEGMedia/Private/Player/FFMPEGMediaOverlaySample.h index 6c0d14a..38e1e43 100644 --- a/Source/FFMPEGMedia/Private/Player/FFMPEGMediaOverlaySample.h +++ b/Source/FFMPEGMedia/Private/Player/FFMPEGMediaOverlaySample.h @@ -75,7 +75,7 @@ class FFFMPEGMediaOverlaySample Duration = (InDuration < FTimespan::Zero()) ? FTimespan::MaxValue() : InDuration; Text = FText::FromString(StrippedText); - Time = InTime; + Time.Time = InTime; Position = InPosition; return true; diff --git a/Source/FFMPEGMedia/Private/Player/FFMPEGMediaPlayer.cpp b/Source/FFMPEGMedia/Private/Player/FFMPEGMediaPlayer.cpp index 909a794..173a14c 100644 --- a/Source/FFMPEGMedia/Private/Player/FFMPEGMediaPlayer.cpp +++ b/Source/FFMPEGMedia/Private/Player/FFMPEGMediaPlayer.cpp @@ -399,7 +399,7 @@ AVFormatContext* FFFMPEGMediaPlayer::ReadContext(const TSharedPtrkey)); - PlayerTasks.Enqueue([=]() + PlayerTasks.Enqueue([this]() { EventSink.ReceiveMediaEvent(EMediaEvent::MediaOpenFailed); }); diff --git a/Source/FFMPEGMedia/Private/Player/FFMPEGMediaTextureSample.h b/Source/FFMPEGMedia/Private/Player/FFMPEGMediaTextureSample.h index cb07e79..d3e7034 100644 --- a/Source/FFMPEGMedia/Private/Player/FFMPEGMediaTextureSample.h +++ b/Source/FFMPEGMedia/Private/Player/FFMPEGMediaTextureSample.h @@ -73,7 +73,7 @@ class FFFMPEGMediaTextureSample Dim = InDim; SampleFormat = EMediaTextureSampleFormat::CharBGRA; Stride = InStride; - Time = InTime; + Time.Time = InTime; return true; } diff --git a/Source/FFMPEGMedia/Private/Player/FFMPEGMediaTracks.cpp b/Source/FFMPEGMedia/Private/Player/FFMPEGMediaTracks.cpp index a65f327..fdce1e0 100644 --- a/Source/FFMPEGMedia/Private/Player/FFMPEGMediaTracks.cpp +++ b/Source/FFMPEGMedia/Private/Player/FFMPEGMediaTracks.cpp @@ -1172,7 +1172,7 @@ bool FFFMPEGMediaTracks::AddStreamToTracks(uint32 StreamIndex, bool IsVideoDevic if (MediaType != AVMEDIA_TYPE_VIDEO && MediaType != AVMEDIA_TYPE_AUDIO && MediaType != AVMEDIA_TYPE_SUBTITLE) { - UE_LOG(LogFFMPEGMedia, Verbose, TEXT("Tracks %p: Unsupported major type %s of stream %i"), this, + UE_LOG(LogFFMPEGMedia, Verbose, TEXT("Tracks %p: Unsupported major type %hs of stream %i"), this, av_get_media_type_string(MediaType), StreamIndex); OutInfo += TEXT("\tUnsupported stream type\n"); @@ -2643,7 +2643,7 @@ int FFFMPEGMediaTracks::AudioDecodeFrame(FTimespan& time, FTimespan& duration) } -void FFFMPEGMediaTracks::RenderAudio() +double FFFMPEGMediaTracks::RenderAudio() { int audio_size, len1; @@ -2690,6 +2690,8 @@ void FFFMPEGMediaTracks::RenderAudio() audioClockSerial, audioCallbackTime / 1000000.0); extclk.SyncToSlave(&audclk); } + + return duration; } void FFFMPEGMediaTracks::StartDisplayThread() @@ -2754,20 +2756,37 @@ int FFFMPEGMediaTracks::AudioRenderThread() { double remaining_time = 0.0; - - int64_t startTime = av_gettime_relative(); + int64_t nextWakeTime = av_gettime_relative(); while (audioRunning) { if (bPrerolled) { - RenderAudio(); - int64_t endTime = av_gettime_relative(); - int64_t dif = endTime - startTime; - if (dif < 33333) + double duration = RenderAudio(); + if (duration > 0.0) + { + int64_t durationUS = (int64_t)(duration * 1000000.0); + nextWakeTime += durationUS; + int64_t now = av_gettime_relative(); + if (nextWakeTime > now) + { + av_usleep(nextWakeTime - now); + } + else + { + if (now - nextWakeTime > 1000000) + nextWakeTime = now; + } + } + else { - av_usleep(33333 - dif); + av_usleep(5000); + nextWakeTime = av_gettime_relative(); } - startTime = endTime; + } + else + { + av_usleep(10000); + nextWakeTime = av_gettime_relative(); } } return 0; @@ -3047,9 +3066,6 @@ int FFFMPEGMediaTracks::VideoThread() return 0; } } - - av_frame_free(&frame); - return 0; } diff --git a/Source/FFMPEGMedia/Private/Player/FFMPEGMediaTracks.h b/Source/FFMPEGMedia/Private/Player/FFMPEGMediaTracks.h index 5947ca0..2799903 100644 --- a/Source/FFMPEGMedia/Private/Player/FFMPEGMediaTracks.h +++ b/Source/FFMPEGMedia/Private/Player/FFMPEGMediaTracks.h @@ -3,10 +3,21 @@ #pragma once +#include + + #include "FFMPEGMediaSettings.h" #include "FFMPEGMediaPrivate.h" #include "FFMPEGFrameQueue.h" #include "FFMPEGClock.h" +#include "IMediaEventSink.h" + +extern "C" { +#include "libavutil/avutil.h" +#include "libavcodec/avcodec.h" +#include "libavformat/avformat.h" +} + #include "CoreTypes.h"