Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stream buffer implementation #270

Merged
merged 36 commits into from
Oct 20, 2022
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
bd24a22
Stream buffer initial implementation
lukasf Jun 23, 2022
3163dad
Reorganize stream buffer files
lukasf Jun 23, 2022
c9fd915
Cleanup solution and editor config
lukasf Jun 23, 2022
8f37cc7
Fine tuning
lukasf Jun 23, 2022
c1a0a1e
Change to task based synchronization
lukasf Jun 24, 2022
4419163
Fix bug in TexturePool
lukasf Jun 24, 2022
cf36315
Fix flush wrong stream after switch streams
lukasf Jun 26, 2022
fed6438
Merge master branch
lukasf Jun 30, 2022
d10392d
Merge master branch
lukasf Jun 30, 2022
6b19a04
Change read ahead to non blocking
lukasf Jun 30, 2022
d34cf7d
Merge master branch
lukasf Jul 18, 2022
62603be
Fix stream buffer for WinRT migration
lukasf Jul 18, 2022
de87a6f
Add deprecation attribute
lukasf Jul 18, 2022
c0e029d
Improve stream buffer for fast seek and normal seek
lukasf Jul 19, 2022
73df120
Work on stream buffer
lukasf Jul 20, 2022
fc55125
Optimize references and seek limit
lukasf Jul 20, 2022
7a4c7b0
Improve config options
lukasf Jul 20, 2022
0e7e3df
Merge master branch
lukasf Jul 24, 2022
4e833a0
Improve buffer and fix possible deadlock after mutex change
lukasf Jul 25, 2022
5d6344f
Merge master branch
lukasf Jul 29, 2022
5d41768
Improve DASH fast seeking
lukasf Jul 29, 2022
efd81c9
Make stream buffer configurable in samples
lukasf Aug 17, 2022
889e7b4
Ignore duplicate seek requests
lukasf Aug 17, 2022
0cfd6ce
Merge master branch
lukasf Aug 21, 2022
5c7f5e5
Simplify MediaSourceConfig
lukasf Aug 18, 2022
d00203a
Optimizations and cleanup for stream buffer
lukasf Aug 21, 2022
f6b67e8
Merge master branch
lukasf Sep 19, 2022
fb61929
Fix RefCue
lukasf Sep 20, 2022
20caef5
Fix bitmap subtitles
lukasf Sep 20, 2022
a278eea
Fix subtitles
lukasf Sep 21, 2022
bfea39b
Disable read ahead buffer by default
lukasf Sep 22, 2022
f271c82
Merge master branch
lukasf Sep 22, 2022
90b2226
Lock on ClearSubtitles
lukasf Sep 22, 2022
7a92a56
Remove unneeded fields
lukasf Sep 22, 2022
0ad52cc
Improve and align sample keyboard shortcuts
lukasf Sep 25, 2022
011b3e1
Fix IsLoopingEnabled not working
lukasf Sep 26, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ root = true
charset = utf-8
indent_style = space
indent_size = 4
end_of_line = lf
end_of_line =crlf
trim_trailing_whitespace = true
insert_final_newline = true

Expand Down
11 changes: 8 additions & 3 deletions FFmpegInteropX.sln
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.136
# Visual Studio Version 16
VisualStudioVersion = 16.0.32002.261
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FFmpegInterop", "Source\FFmpegInteropX.vcxproj", "{9CFA3B3E-B7AF-4629-84E2-C962C5B046B1}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FFmpegInteropX", "Source\FFmpegInteropX.vcxproj", "{9CFA3B3E-B7AF-4629-84E2-C962C5B046B1}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MediaPlayerCPP", "Samples\MediaPlayerCPP\MediaPlayerCPP.vcxproj", "{9C0EB7EC-6FED-46E7-9CC9-F36132050AA1}"
EndProject
Expand All @@ -14,6 +14,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaPlayerCS", "Samples\Me
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTest", "Tests\UnitTest.csproj", "{F1ECBD62-71FE-47FB-B588-1E331A375B59}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F6A9745D-66E3-42BC-8124-BA173E9E781C}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Expand Down
63 changes: 49 additions & 14 deletions Samples/MediaPlayerCPP/MainPage.xaml.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//*****************************************************************************
//*****************************************************************************
//
// Copyright 2015 Microsoft Corporation
//
Expand Down Expand Up @@ -83,17 +83,31 @@ void MediaPlayerCPP::MainPage::OnButtonPressed(Windows::Media::SystemMediaTransp

task<void> MainPage::TryOpenLastFile()
{
try
{
//Try open last file
auto file = co_await StorageApplicationPermissions::FutureAccessList->GetFileAsync(
StorageApplicationPermissions::FutureAccessList->Entries->GetAt(0).Token);
co_await OpenLocalFile(file);
}
catch (Exception^ ex)
{
DisplayErrorMessage(ex->Message);
}
try
{
//Try open last file
auto file = co_await StorageApplicationPermissions::FutureAccessList->GetFileAsync(
StorageApplicationPermissions::FutureAccessList->Entries->GetAt(0).Token);
co_await OpenLocalFile(file);
}
catch (Exception^ ex)
{
DisplayErrorMessage(ex->Message);
}
}

task<void> MainPage::TryOpenLastUri()
{
try
{
//Try open last uri
auto uri = (String^)ApplicationData::Current->LocalSettings->Values->Lookup("LastUri");
co_await OpenUriStream(uri);
}
catch (Exception^ ex)
{
DisplayErrorMessage(ex->Message);
}
}

void MainPage::OpenLocalFile(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
Expand Down Expand Up @@ -192,6 +206,8 @@ task<void> MainPage::OpenUriStream(Platform::String^ uri)

// Close control panel after opening media
Splitter->IsPaneOpen = false;

ApplicationData::Current->LocalSettings->Values->Insert("LastUri", uri);
}
catch (Exception^ ex)
{
Expand Down Expand Up @@ -477,14 +493,33 @@ void MediaPlayerCPP::MainPage::OnKeyDown(Windows::UI::Core::CoreWindow^ sender,
TryOpenLastFile();
}

if (args->VirtualKey == Windows::System::VirtualKey::Enter && (Window::Current->CoreWindow->GetKeyState(Windows::System::VirtualKey::Shift) & Windows::UI::Core::CoreVirtualKeyStates::Down)
== Windows::UI::Core::CoreVirtualKeyStates::Down && ApplicationData::Current->LocalSettings->Values->HasKey("LastUri"))
{
TryOpenLastUri();
}

if (args->VirtualKey == Windows::System::VirtualKey::V)
{
if (playbackItem && playbackItem->VideoTracks->Size > 1)
{
playbackItem->VideoTracks->SelectedIndex =
(playbackItem->VideoTracks->SelectedIndex + 1) % playbackItem->VideoTracks->Size;
bool reverse = (Window::Current->CoreWindow->GetKeyState(Windows::System::VirtualKey::Shift) & Windows::UI::Core::CoreVirtualKeyStates::Down) == Windows::UI::Core::CoreVirtualKeyStates::Down;
int index = reverse ?
(playbackItem->VideoTracks->SelectedIndex - 1) % playbackItem->VideoTracks->Size :
(playbackItem->VideoTracks->SelectedIndex + 1) % playbackItem->VideoTracks->Size;
playbackItem->VideoTracks->SelectedIndex = index;
}
}

if (args->VirtualKey == Windows::System::VirtualKey::Right && FFmpegMSS && mediaPlayer->PlaybackSession->CanSeek)
{
mediaPlayer->PlaybackSession->Position = TimeSpan{ mediaPlayer->PlaybackSession->Position.Duration + 50000000 };
}

if (args->VirtualKey == Windows::System::VirtualKey::Left && FFmpegMSS && mediaPlayer->PlaybackSession->CanSeek)
{
mediaPlayer->PlaybackSession->Position = TimeSpan{ mediaPlayer->PlaybackSession->Position.Duration - 50000000 };
}
}


Expand Down
5 changes: 3 additions & 2 deletions Samples/MediaPlayerCPP/MainPage.xaml.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//*****************************************************************************
//*****************************************************************************
//
// Copyright 2015 Microsoft Corporation
//
Expand Down Expand Up @@ -43,7 +43,8 @@ namespace MediaPlayerCPP
void OpenLocalFile(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
task<void> OpenLocalFile();
task<void> OpenLocalFile(Windows::Storage::StorageFile^ file);
task<void> TryOpenLastFile();
task<void> TryOpenLastFile();
task<void> TryOpenLastUri();
void URIBoxKeyUp(Platform::Object^ sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e);
task<void> OpenUriStream(Platform::String^ uri);
void MediaFailed(Platform::Object^ sender, Windows::UI::Xaml::ExceptionRoutedEventArgs^ e);
Expand Down
80 changes: 59 additions & 21 deletions Samples/MediaPlayerCS/MainPage.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//*****************************************************************************
//*****************************************************************************
//
// Copyright 2015 Microsoft Corporation
//
Expand Down Expand Up @@ -92,14 +92,33 @@ private async void MainPage_KeyDown(CoreWindow sender, KeyEventArgs args)
{
await TryOpenLastFile();
}
if (args.VirtualKey == VirtualKey.Enter && (Window.Current.CoreWindow.GetKeyState(VirtualKey.Shift) & CoreVirtualKeyStates.Down)
== CoreVirtualKeyStates.Down && ApplicationData.Current.LocalSettings.Values.ContainsKey("LastUri"))
{
await TryOpenLastUri();
}

if (args.VirtualKey == VirtualKey.V)
{
if (playbackItem != null && playbackItem.VideoTracks.Count > 1)
{
playbackItem.VideoTracks.SelectedIndex =
bool reverse = (Window.Current.CoreWindow.GetKeyState(VirtualKey.Control) & CoreVirtualKeyStates.Down) == CoreVirtualKeyStates.Down;
int index = reverse ?
(playbackItem.VideoTracks.SelectedIndex - 1) % playbackItem.VideoTracks.Count :
(playbackItem.VideoTracks.SelectedIndex + 1) % playbackItem.VideoTracks.Count;
playbackItem.VideoTracks.SelectedIndex = index;
}
}

if (args.VirtualKey == VirtualKey.Right && FFmpegMSS != null && mediaPlayer.PlaybackSession.CanSeek)
{
mediaPlayer.PlaybackSession.Position += TimeSpan.FromSeconds(5);
}

if (args.VirtualKey == VirtualKey.Left && FFmpegMSS != null && mediaPlayer.PlaybackSession.CanSeek)
{
mediaPlayer.PlaybackSession.Position -= TimeSpan.FromSeconds(5);
}
}

private async void CodecChecker_CodecRequired(object sender, CodecRequiredEventArgs args)
Expand Down Expand Up @@ -151,6 +170,18 @@ private async Task TryOpenLastFile()
{
}
}
private async Task TryOpenLastUri()
{
try
{
//Try open last uri
var uri = (string)ApplicationData.Current.LocalSettings.Values["LastUri"];
await OpenStreamUri(uri);
}
catch (Exception)
{
}
}

public MediaSourceConfig Config { get; set; }

Expand Down Expand Up @@ -225,30 +256,37 @@ private async void URIBoxKeyUp(object sender, KeyRoutedEventArgs e)
// Mark event as handled to prevent duplicate event to re-triggered
e.Handled = true;

try
{
// Set FFmpeg specific options. List of options can be found in https://www.ffmpeg.org/ffmpeg-protocols.html
await OpenStreamUri(uri);
}
}

// Below are some sample options that you can set to configure RTSP streaming
// Config.FFmpegOptions.Add("rtsp_flags", "prefer_tcp");
// Config.FFmpegOptions.Add("stimeout", 100000);
private async Task OpenStreamUri(string uri)
{
try
{
// Set FFmpeg specific options. List of options can be found in https://www.ffmpeg.org/ffmpeg-protocols.html

// Instantiate FFmpegMediaSource using the URI
mediaPlayer.Source = null;
FFmpegMSS = await FFmpegMediaSource.CreateFromUriAsync(uri, Config);
// Below are some sample options that you can set to configure RTSP streaming
// Config.FFmpegOptions.Add("rtsp_flags", "prefer_tcp");
// Config.FFmpegOptions.Add("stimeout", 100000);

var source = FFmpegMSS.CreateMediaPlaybackItem();
// Instantiate FFmpegMediaSource using the URI
mediaPlayer.Source = null;
FFmpegMSS = await FFmpegMediaSource.CreateFromUriAsync(uri, Config);

// Pass MediaStreamSource to Media Element
mediaPlayer.Source = source;
var source = FFmpegMSS.CreateMediaPlaybackItem();

// Close control panel after opening media
Splitter.IsPaneOpen = false;
}
catch (Exception ex)
{
await DisplayErrorMessage(ex.Message);
}
// Pass MediaStreamSource to Media Element
mediaPlayer.Source = source;

// Close control panel after opening media
Splitter.IsPaneOpen = false;

ApplicationData.Current.LocalSettings.Values["LastUri"] = uri;
}
catch (Exception ex)
{
await DisplayErrorMessage(ex.Message);
}
}

Expand Down
2 changes: 1 addition & 1 deletion Samples/MediaPlayerCS/MediaPlayerCS.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@
<ItemGroup>
<ProjectReference Include="..\..\Source\FFmpegInteropX.vcxproj">
<Project>{9cfa3b3e-b7af-4629-84e2-c962c5b046b1}</Project>
<Name>FFmpegInterop</Name>
<Name>FFmpegInteropX</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
Expand Down
10 changes: 7 additions & 3 deletions Source/D3D11VideoSampleProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,10 @@ namespace FFmpegInteropX
{
if (sample->Direct3D11Surface)
{
samples.insert(reinterpret_cast<IUnknown*>(sample));
// AddRef the sample on native interface to prevent it from being collected before Processed is called
auto sampleNative = reinterpret_cast<IUnknown*>(sample);
sampleNative->AddRef();

sample->Processed += ref new Windows::Foundation::TypedEventHandler<Windows::Media::Core::MediaStreamSample^, Platform::Object^>(this, &D3D11VideoSampleProvider::OnProcessed);
}

Expand All @@ -145,7 +148,9 @@ namespace FFmpegInteropX
texturePool->ReturnTexture(texture);
}

samples.erase(reinterpret_cast<IUnknown*>(sender));
// Release the sample's native interface
auto sampleNative = reinterpret_cast<IUnknown*>(sender);
sampleNative->Release();

SAFE_RELEASE(surface);
SAFE_RELEASE(texture);
Expand Down Expand Up @@ -379,7 +384,6 @@ namespace FFmpegInteropX
}

TexturePool^ texturePool;
std::set<IUnknown*> samples;

};
}
Expand Down
2 changes: 2 additions & 0 deletions Source/FFmpegInteropX.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
<AdditionalOptions>/bigobj /await /d2CoroOptsWorkaround %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>28204;4635</DisableSpecificWarnings>
<GenerateXMLDocumentationFiles>true</GenerateXMLDocumentationFiles>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<AdditionalDependencies>shcore.lib;runtimeobject.lib;mfuuid.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies>
Expand Down Expand Up @@ -130,6 +131,7 @@
<ClInclude Include="NativeBuffer.h" />
<ClInclude Include="NativeBufferFactory.h" />
<ClInclude Include="ReferenceCue.h" />
<ClInclude Include="StreamBuffer.h" />
<ClInclude Include="StreamInfo.h" />
<ClInclude Include="StringUtils.h" />
<ClInclude Include="SubtitleProvider.h" />
Expand Down
1 change: 1 addition & 0 deletions Source/FFmpegInteropX.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@
<ClInclude Include="DirectXInteropHelper.h">
<Filter>Helpers</Filter>
</ClInclude>
<ClInclude Include="StreamBuffer.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\Build\FFmpegConfig.sh">
Expand Down
Loading