Ejemplo n.º 1
0
        internal T GetInteropDelegate <T>()
        {
            string vlcFunctionName = null;

            try
            {
#if NETSTANDARD1_3
                var attrs = typeof(T).GetTypeInfo().GetCustomAttributes(typeof(LibVlcFunctionAttribute), false).ToArray();
#else
                var attrs = typeof(T).GetCustomAttributes(typeof(LibVlcFunctionAttribute), false);
#endif
                if (attrs.Length == 0)
                {
                    throw new Exception("Could not find the LibVlcFunctionAttribute.");
                }
                var attr = (LibVlcFunctionAttribute)attrs[0];
                vlcFunctionName = attr.FunctionName;

                lock (this._myInteropDelegatesLockObject)
                {
                    if (myInteropDelegates.ContainsKey(vlcFunctionName))
                    {
                        return((T)myInteropDelegates[attr.FunctionName]);
                    }

                    var procAddress = Win32Interops.GetProcAddress(myLibVlcDllHandle, attr.FunctionName);
                    if (procAddress == IntPtr.Zero)
                    {
                        throw new Win32Exception();
                    }

                    var delegateForFunctionPointer = MarshalHelper.GetDelegateForFunctionPointer <T>(procAddress);

                    myInteropDelegates[attr.FunctionName] = delegateForFunctionPointer;

                    return(delegateForFunctionPointer);
                }
            }
            catch (Win32Exception e)
            {
                throw new MissingMethodException(string.Format("The address of the function '{0}' does not exist in libvlc library.", vlcFunctionName), e);
            }
        }
        /// <summary>
        /// Register callbacks in order to handle VLC dialogs. LibVLC 3.0.0 and later.
        /// </summary>
        public void SetDialogCallbacks(DialogCallbacks?callbacks, IntPtr data)
        {
            if (VlcVersionNumber.Major < 3)
            {
                throw new InvalidOperationException($"You need VLC version 3.0 or higher to be able to use {nameof(SetDialogCallbacks)}");
            }

            if (this.dialogCallbacks.HasValue)
            {
                Marshal.FreeHGlobal(this.dialogCallbacksPointer);
                this.dialogCallbacksPointer = IntPtr.Zero;
            }

            this.dialogCallbacks = callbacks;
            if (this.dialogCallbacks.HasValue)
            {
                this.dialogCallbacksPointer = Marshal.AllocHGlobal(MarshalHelper.SizeOf <DialogCallbacks>());
                Marshal.StructureToPtr(this.dialogCallbacks.Value, this.dialogCallbacksPointer, false);
            }

            myLibraryLoader.GetInteropDelegate <SetDialogCallbacks>().Invoke(this.myVlcInstance, this.dialogCallbacksPointer, data);
        }
        public MediaTrack[] GetMediaTracks(VlcMediaInstance mediaInstance)
        {
            if (mediaInstance == IntPtr.Zero)
            {
                throw new ArgumentException("Media instance is not initialized.");
            }

            var cpt = GetInteropDelegate <GetMediaTracks>().Invoke(mediaInstance, out var fullBuffer);

            if (cpt <= 0)
            {
                return(new MediaTrack[0]);
            }
            try
            {
                var result = new MediaTrack[cpt];
                for (int index = 0; index < cpt; index++)
                {
                    var current = MarshalHelper.PtrToStructure <LibvlcMediaTrackT>(Marshal.ReadIntPtr(fullBuffer, index * MarshalHelper.SizeOf <IntPtr>()));

                    TrackInfo trackInfo = null;

                    switch (current.Type)
                    {
                    case MediaTrackTypes.Audio:
                        var audio = MarshalHelper.PtrToStructure <LibvlcAudioTrackT>(current.TypedTrack);
                        trackInfo = new AudioTrack
                        {
                            Channels = audio.Channels,
                            Rate     = audio.Rate
                        };
                        break;

                    case MediaTrackTypes.Video:
                        var video = MarshalHelper.PtrToStructure <LibvlcVideoTrackT>(current.TypedTrack);
                        trackInfo = new VideoTrack
                        {
                            Height       = video.Height,
                            Width        = video.Width,
                            SarNum       = video.SarNum,
                            SarDen       = video.SarDen,
                            FrameRateNum = video.FrameRateNum,
                            FrameRateDen = video.FrameRateDen,
                            Orientation  = video.Orientation,
                            Projection   = video.Projection,
                            Pose         = video.Pose
                        };
                        break;

                    case MediaTrackTypes.Text:
                        var text = MarshalHelper.PtrToStructure <LibvlcSubtitleTrackT>(current.TypedTrack);
                        trackInfo = new SubtitleTrack
                        {
                            Encoding = Utf8InteropStringConverter.Utf8InteropToString(text.Encoding)
                        };
                        break;
                    }

                    result[index] = new MediaTrack
                    {
                        CodecFourcc    = current.Codec,
                        OriginalFourcc = current.OriginalFourCC,
                        Id             = current.Id,
                        Type           = current.Type,
                        Profile        = current.Profile,
                        Level          = current.Level,
                        TrackInfo      = trackInfo,
                        Bitrate        = current.Bitrate,
                        Language       = Utf8InteropStringConverter.Utf8InteropToString(current.Language),
                        Description    = Utf8InteropStringConverter.Utf8InteropToString(current.Description)
                    };
                }
                return(result);
            }
            finally
            {
                GetInteropDelegate <ReleaseMediaTracks>().Invoke(fullBuffer, cpt);
            }
        }