Skip to content

Commit

Permalink
remove setting of the seekable field (#663)
Browse files Browse the repository at this point in the history
* remove setting of the seekable field

remove setting of the seekable field, since it causes access violation errors, and unnecessary.

Check the comment from june 6, 2023: #642

Or:
Ruslan-B/FFmpeg.AutoGen#255

Currently I'm uusing my own package, but I'd liek to swicth your original version, but this issue block me.

Reproduce the issue: Just open any local video file with the following url:
customfile://C:\myfolder\myfile.mkv
It will use the FileInputStream which sets the seekable field. => access violation when trying to open the media.

* fix the hw acceleration

* using fix
  • Loading branch information
zgabi authored Jun 26, 2024
1 parent b9336b6 commit 6ceff20
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 31 deletions.
9 changes: 5 additions & 4 deletions Unosquare.FFME.Windows.Sample/MainWindow.MediaEvents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using ClosedCaptions;
using FFmpeg.AutoGen;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
Expand Down Expand Up @@ -286,16 +287,16 @@ private async void OnMediaOpening(object sender, MediaOpeningEventArgs e)
// Hardware device selection
if (videoStream.FPS <= 30)
{
var devices = new List<HardwareDeviceInfo>(deviceCandidates.Length);
foreach (var deviceType in deviceCandidates)
{
var accelerator = videoStream.HardwareDevices.FirstOrDefault(d => d.DeviceType == deviceType);
if (accelerator == null) continue;

if (Debugger.IsAttached)
e.Options.VideoHardwareDevice = accelerator;

break;
devices.Add(accelerator);
}

e.Options.VideoHardwareDevices = devices.ToArray();
}

// Start building a video filter
Expand Down
2 changes: 1 addition & 1 deletion Unosquare.FFME/Common/MediaOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ internal MediaOptions()
/// Use Stream's HardwareDevices property to get a list of
/// compatible hardware accelerators.
/// </summary>
public HardwareDeviceInfo VideoHardwareDevice { get; set; }
public HardwareDeviceInfo[] VideoHardwareDevices { get; set; }

/// <summary>
/// Prevent reading from audio stream components.
Expand Down
2 changes: 1 addition & 1 deletion Unosquare.FFME/Container/MediaComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ protected MediaComponent(MediaContainer container, int streamIndex)
codecOptions.SetCopyOpaque();

// Enable Hardware acceleration if requested
(this as VideoComponent)?.AttachHardwareDevice(container.MediaOptions.VideoHardwareDevice);
(this as VideoComponent)?.AttachHardwareDevice(container.MediaOptions.VideoHardwareDevices);

// Open the CodecContext. This requires exclusive FFmpeg access
lock (CodecLock)
Expand Down
3 changes: 0 additions & 3 deletions Unosquare.FFME/Container/MediaContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -682,9 +682,6 @@ private void StreamInitialize()
CustomInputStreamContext = ffmpeg.avio_alloc_context(
inputBuffer, CustomInputStream.ReadBufferLength, 0, null, CustomInputStreamRead, null, CustomInputStreamSeek);

// Set the seekable flag based on the custom input stream implementation
CustomInputStreamContext->seekable = CustomInputStream.CanSeek ? ffmpeg.AVIO_SEEKABLE_NORMAL : 0;

// Assign the AVIOContext to the input context
inputContextPtr->pb = CustomInputStreamContext;
}
Expand Down
48 changes: 26 additions & 22 deletions Unosquare.FFME/Container/VideoComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,37 +157,41 @@ internal VideoComponent(MediaContainer container, int streamIndex)
/// <summary>
/// Attaches a hardware accelerator to this video component.
/// </summary>
/// <param name="selectedConfig">The selected configuration.</param>
/// <param name="selectedConfigs">The selected configurations.</param>
/// <returns>
/// Whether or not the hardware accelerator was attached.
/// </returns>
public bool AttachHardwareDevice(HardwareDeviceInfo selectedConfig)
public bool AttachHardwareDevice(HardwareDeviceInfo[] selectedConfigs)
{
// Check for no device selection
if (selectedConfig == null)
if (selectedConfigs == null || selectedConfigs.Length == 0)
return false;

try
{
var accelerator = new HardwareAccelerator(this, selectedConfig);

AVBufferRef* devContextRef = null;
var initResultCode = ffmpeg.av_hwdevice_ctx_create(&devContextRef, accelerator.DeviceType, null, null, 0);
if (initResultCode < 0)
throw new MediaContainerException($"Unable to initialize hardware context for device {accelerator.Name}");

HardwareDeviceContext = devContextRef;
HardwareAccelerator = accelerator;
CodecContext->hw_device_ctx = ffmpeg.av_buffer_ref(HardwareDeviceContext);
CodecContext->get_format = accelerator.GetFormatCallback;

return true;
}
catch (Exception ex)
foreach (var selectedConfig in selectedConfigs)
{
this.LogError(Aspects.Component, "Could not attach hardware decoder.", ex);
return false;
try
{
AVBufferRef* devContextRef = null;
var initResultCode = ffmpeg.av_hwdevice_ctx_create(&devContextRef, selectedConfig.DeviceType, null, null, 0);
if (initResultCode < 0)
continue;

var accelerator = new HardwareAccelerator(this, selectedConfig);
HardwareDeviceContext = devContextRef;
HardwareAccelerator = accelerator;
CodecContext->hw_device_ctx = ffmpeg.av_buffer_ref(HardwareDeviceContext);
CodecContext->get_format = accelerator.GetFormatCallback;

return true;
}
catch (Exception ex)
{
this.LogError(Aspects.Component, "Could not attach hardware decoder.", ex);
}
}

this.LogError(Aspects.Component, "Could not attach any hardware decoder.");
return false;
}

/// <summary>
Expand Down

0 comments on commit 6ceff20

Please sign in to comment.