Exemplo n.º 1
0
        /// <summary>
        /// Initializes static members of the <see cref="MediaElement"/> class.
        /// </summary>
        static MediaElement()
        {
            var style = new Style(typeof(MediaElement), null);

            style.Setters.Add(new Setter(FlowDirectionProperty, FlowDirection.LeftToRight));
            style.Seal();
            StyleProperty.OverrideMetadata(typeof(MediaElement), new FrameworkPropertyMetadata(style));

            // Platform specific implementation
            Platform.SetDllDirectory = NativeMethods.SetDllDirectory;
            Platform.CopyMemory      = NativeMethods.CopyMemory;
            Platform.FillMemory      = NativeMethods.FillMemory;
            Platform.CreateTimer     = (priority) =>
            {
                return(new CustomDispatcherTimer((DispatcherPriority)priority));
            };

            // Setup the Platform-specific factory callbacks
            Platform.UIInvoke        = (priority, action) => WPFUtils.UIInvoke((DispatcherPriority)priority, action);
            Platform.UIEnqueueInvoke = (priority, action, args) => WPFUtils.UIEnqueueInvoke((DispatcherPriority)priority, action, args);
            Platform.CreateRenderer  = (mediaType, m) =>
            {
                if (mediaType == MediaType.Audio)
                {
                    return(new AudioRenderer(m));
                }
                else if (mediaType == MediaType.Video)
                {
                    return(new VideoRenderer(m));
                }
                else if (mediaType == MediaType.Subtitle)
                {
                    return(new SubtitleRenderer(m));
                }

                throw new ArgumentException($"No suitable renderer for Media Type '{mediaType}'");
            };

            // Simply forward the calls
            MediaElementCore.FFmpegMessageLogged += (o, e) => FFmpegMessageLogged?.Invoke(o, e);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Sets the text to be rendered on the text blocks.
        /// Returns immediately because it enqueues the action on the UI thread.
        /// </summary>
        /// <param name="text">The text.</param>
        private async void SetText(string text)
        {
            if (RenderedText.Equals(text))
            {
                return;
            }

            // We fire-and-forget the update of the text
            await WPFUtils.UIEnqueueInvoke(
                DispatcherPriority.DataBind,
                new Action <string>((s) =>
            {
                lock (SyncLock)
                {
                    var textBlocks = GetTextBlocks();
                    foreach (var tb in textBlocks)
                    {
                        tb.Text = s;
                    }

                    RenderedText = s;
                }
            }), text);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Renders the specified media block.
        /// This needs to return immediately so the calling thread is not disturbed.
        /// </summary>
        /// <param name="mediaBlock">The media block.</param>
        /// <param name="clockPosition">The clock position.</param>
        public async void Render(MediaBlock mediaBlock, TimeSpan clockPosition)
        {
            var block = mediaBlock as VideoBlock;

            if (block == null)
            {
                return;
            }
            if (IsRenderingInProgress.Value == true)
            {
                MediaElement.Logger.Log(MediaLogMessageType.Debug, $"{nameof(VideoRenderer)}: Frame skipped at {mediaBlock.StartTime}");
                return;
            }

            IsRenderingInProgress.Value = true;

            await WPFUtils.UIEnqueueInvoke(
                DispatcherPriority.Render,
                new Action <VideoBlock, TimeSpan>((b, cP) =>
            {
                try
                {
                    // Skip rendering if Scrubbing is not enabled
                    if (MediaElement.ScrubbingEnabled == false && MediaElement.IsPlaying == false)
                    {
                        return;
                    }

                    if (TargetBitmap == null || TargetBitmap.PixelWidth != b.PixelWidth || TargetBitmap.PixelHeight != b.PixelHeight)
                    {
                        InitializeTargetBitmap(b);
                    }

                    var updateRect = new Int32Rect(0, 0, b.PixelWidth, b.PixelHeight);
                    TargetBitmap.WritePixels(updateRect, b.Buffer, b.BufferLength, b.BufferStride);
                    MediaElementCore.VideoSmtpeTimecode = b.SmtpeTimecode;
                    MediaElementCore.VideoHardwareDecoder = (MediaElementCore.Container?.Components?.Video?.IsUsingHardwareDecoding ?? false) ?
                                                            MediaElementCore.Container?.Components?.Video?.HardwareAccelerator?.Name ?? string.Empty : string.Empty;

                    MediaElement.RaiseRenderingVideoEvent(
                        TargetBitmap,
                        MediaElementCore.Container.MediaInfo.Streams[b.StreamIndex],
                        b.SmtpeTimecode,
                        b.DisplayPictureNumber,
                        b.StartTime,
                        b.Duration,
                        cP);

                    ApplyScaleTransform(b);
                }
                catch (Exception ex)
                {
                    Utils.Log(MediaElement, MediaLogMessageType.Error, $"{nameof(VideoRenderer)} {ex.GetType()}: {ex.Message}. Stack Trace:\r\n{ex.StackTrace}");
                }
                finally
                {
                    IsRenderingInProgress.Value = false;
                }
            }), block,
                clockPosition);
        }