正确使用 libvlc_media_open_cb
Proper use of libvlc_media_open_cb
我正在尝试使用 libvlc_media_new_callbacks
函数使用 libvlc 从内存中播放媒体。此函数需要指向四个回调函数的指针:Open
、Read
、Seek
和 Close
.
Declare Function libvlc_media_new_callbacks Lib "libvlc.dll" (Instance As Ptr, OpenCB As Ptr, ReadCB As Ptr, SeekCB As Ptr, CloseCB As Ptr, Opaque As Ptr) As Ptr
Dim opaque As Ptr = SomeOpaqueValue()
Dim handle As Ptr = libvlc_media_new_callbacks(instance, AddressOf MediaOpen, AddressOf MediaRead, AddressOf MediaSeek, AddressOf MediaClose, opaque)
如果我不指定 Open
回调,Read
、Seek
和 Close
回调都可以正常工作,但这意味着 libvlc 不知道如何媒体长。
当我 do 指定一个 Open
回调时,它会使用正确的 opaque
参数调用,但其他回调会得到一个空指针。这使得无法知道回调应该在哪个流上工作。
我是不是误解了打开回调的目的?
这是我的回调函数:
Shared Function MediaOpen(Opaque As Ptr, Buffer As Ptr, ByRef BufferSize As UInt64) As UInt32
Dim r As BinaryStream = Streams.Lookup(Opaque, Nil)
If r = Nil Then Return 1 ' invalid Opaque
Buffer = Nil ' Not sure what to do with this parameter
BufferSize = r.Length
Return 0
End Function
Shared Sub MediaClose(Opaque As Ptr)
If Streams.HasKey(Opaque) Then Streams.Remove(Opaque)
If Streams.Count = 0 Then Streams = Nil
End Sub
Shared Function MediaRead(Opaque As Ptr, Buffer As Ptr, BufferSize As Integer) As UInt32
Dim r As BinaryStream = Streams.Lookup(Opaque, Nil)
If r = Nil Then Return 0 ' invalid Opaque
Dim mb As MemoryBlock = Buffer
Dim data As MemoryBlock = r.Read(BufferSize)
mb.StringValue(0, data.Size) = data
Return data.Size
End Function
Shared Function MediaSeek(Opaque As Ptr, Offset As UInt64) As Int32
Dim r As BinaryStream = Streams.Lookup(Opaque, Nil)
If r = Nil Then Return 1 ' invalid Opaque
If Offset > r.Length Then Return 1 ' invalid offset
r.Position = Offset
Return 0
End Function
根据文档,您必须在打开的 Buffer 参数中分配一个缓冲区和 return 它的地址(为此您需要将其更改为 ByRef 参数!)。然后您将获得在其他函数中传递的相同缓冲区指针。
理想情况下,您可以设置
Buffer = r
在 MediaOpen 中。但是Xojo不会让你的。相反,您需要维护一个存储 r
的字典,然后将其与您可以分配给 Buffer 参数的值相关联。
这是一个示例(未测试):
Static Property OpenedBuffers as Dictionary
Static Property OpenedBufferID as Integer
Shared Function MediaOpen(Opaque As Ptr, ByRef HandleOut As Integer, ByRef BufferSize As UInt64) As UInt32
Dim r As BinaryStream = Streams.Lookup(Opaque, Nil)
If r = Nil Then Return 1 ' invalid Opaque
if OpenedBuffers = nil then OpenedBuffers = new Dictionary
OpenedBufferID = OpenedBufferID + 1
OpenedBuffers.Value(OpenedBufferID) = r
HandleOut = OpenedBufferID
BufferSize = r.Length
Return 0
End Function
Shared Function MediaRead(Handle As Integer, Buffer As Ptr, BufferSize As Integer) As UInt32
Dim r As BinaryStream = OpenedBuffers.Value(Handle)
...
Shared Sub MediaClose(Handle As Integer)
Dim r As BinaryStream = OpenedBuffers.Value(Handle)
OpenedBuffers.Remove (Handle)
If Streams.HasKey(r) Then Streams.Remove(r)
...
希望对您有所帮助
我正在尝试使用 libvlc_media_new_callbacks
函数使用 libvlc 从内存中播放媒体。此函数需要指向四个回调函数的指针:Open
、Read
、Seek
和 Close
.
Declare Function libvlc_media_new_callbacks Lib "libvlc.dll" (Instance As Ptr, OpenCB As Ptr, ReadCB As Ptr, SeekCB As Ptr, CloseCB As Ptr, Opaque As Ptr) As Ptr
Dim opaque As Ptr = SomeOpaqueValue()
Dim handle As Ptr = libvlc_media_new_callbacks(instance, AddressOf MediaOpen, AddressOf MediaRead, AddressOf MediaSeek, AddressOf MediaClose, opaque)
如果我不指定 Open
回调,Read
、Seek
和 Close
回调都可以正常工作,但这意味着 libvlc 不知道如何媒体长。
当我 do 指定一个 Open
回调时,它会使用正确的 opaque
参数调用,但其他回调会得到一个空指针。这使得无法知道回调应该在哪个流上工作。
我是不是误解了打开回调的目的?
这是我的回调函数:
Shared Function MediaOpen(Opaque As Ptr, Buffer As Ptr, ByRef BufferSize As UInt64) As UInt32
Dim r As BinaryStream = Streams.Lookup(Opaque, Nil)
If r = Nil Then Return 1 ' invalid Opaque
Buffer = Nil ' Not sure what to do with this parameter
BufferSize = r.Length
Return 0
End Function
Shared Sub MediaClose(Opaque As Ptr)
If Streams.HasKey(Opaque) Then Streams.Remove(Opaque)
If Streams.Count = 0 Then Streams = Nil
End Sub
Shared Function MediaRead(Opaque As Ptr, Buffer As Ptr, BufferSize As Integer) As UInt32
Dim r As BinaryStream = Streams.Lookup(Opaque, Nil)
If r = Nil Then Return 0 ' invalid Opaque
Dim mb As MemoryBlock = Buffer
Dim data As MemoryBlock = r.Read(BufferSize)
mb.StringValue(0, data.Size) = data
Return data.Size
End Function
Shared Function MediaSeek(Opaque As Ptr, Offset As UInt64) As Int32
Dim r As BinaryStream = Streams.Lookup(Opaque, Nil)
If r = Nil Then Return 1 ' invalid Opaque
If Offset > r.Length Then Return 1 ' invalid offset
r.Position = Offset
Return 0
End Function
根据文档,您必须在打开的 Buffer 参数中分配一个缓冲区和 return 它的地址(为此您需要将其更改为 ByRef 参数!)。然后您将获得在其他函数中传递的相同缓冲区指针。
理想情况下,您可以设置
Buffer = r
在 MediaOpen 中。但是Xojo不会让你的。相反,您需要维护一个存储 r
的字典,然后将其与您可以分配给 Buffer 参数的值相关联。
这是一个示例(未测试):
Static Property OpenedBuffers as Dictionary
Static Property OpenedBufferID as Integer
Shared Function MediaOpen(Opaque As Ptr, ByRef HandleOut As Integer, ByRef BufferSize As UInt64) As UInt32
Dim r As BinaryStream = Streams.Lookup(Opaque, Nil)
If r = Nil Then Return 1 ' invalid Opaque
if OpenedBuffers = nil then OpenedBuffers = new Dictionary
OpenedBufferID = OpenedBufferID + 1
OpenedBuffers.Value(OpenedBufferID) = r
HandleOut = OpenedBufferID
BufferSize = r.Length
Return 0
End Function
Shared Function MediaRead(Handle As Integer, Buffer As Ptr, BufferSize As Integer) As UInt32
Dim r As BinaryStream = OpenedBuffers.Value(Handle)
...
Shared Sub MediaClose(Handle As Integer)
Dim r As BinaryStream = OpenedBuffers.Value(Handle)
OpenedBuffers.Remove (Handle)
If Streams.HasKey(r) Then Streams.Remove(r)
...
希望对您有所帮助