/// <summary>
 /// Update the subtitle texture from a Bitmap.
 /// </summary>
 /// <param name="subtitle"></param>
 private void SetSubtitle(Subtitle subtitle)
 {
   Texture texture = null;
   ServiceRegistration.Get<ILogger>().Debug("SubtitleRenderer: SetSubtitle : " + subtitle);
   if (subtitle != null)
   {
     try
     {
       Bitmap bitmap = subtitle.SubBitmap;
       if (bitmap != null)
       {
         using (MemoryStream stream = new MemoryStream())
         {
           ImageInformation imageInformation;
           bitmap.Save(stream, ImageFormat.Bmp);
           stream.Position = 0;
           texture = Texture.FromStream(_device, stream, (int) stream.Length, (int) subtitle.Width,
                                        (int) subtitle.Height, 1,
                                        Usage.Dynamic, Format.A8R8G8B8, Pool.Default, Filter.None, Filter.None, 0,
                                        out imageInformation);
         }
         // Free bitmap
         FilterGraphTools.TryDispose(ref subtitle.SubBitmap);
       }
     }
     catch (Exception e)
     {
       ServiceRegistration.Get<ILogger>().Error("SubtitleRenderer: Failed to create subtitle texture!!!", e);
       return;
     }
   }
   // Set new subtitle
   lock (_syncObj)
   {
     // Dispose of old subtitle
     FilterGraphTools.TryDispose(ref _subTexture);
     _subTexture = texture;
     _currentSubtitle = subtitle;
   }
 }
    private void SetMatchingSubTitle()
    {
      lock (_syncObj)
      {
        if (_player == null)
          return;

        if (_clearOnNextRender)
        {
          _clearOnNextRender = false;
          _currentSubtitle = null;
          FilterGraphTools.TryDispose(ref _subTexture);
        }

        if (_renderSubtitles == false)
          return;
      }

      double currentTime = _player.CurrentTime.TotalSeconds;
      Subtitle currentSubtitle;
      lock (_syncObj)
      {
        _currentTime = currentTime;
        currentSubtitle = _currentSubtitle;
      }

      // If we currently have a subtitle an it is in current time, no need to look for another one yet
      if (currentSubtitle != null && currentSubtitle.PresentTime <= currentTime && currentTime <= currentSubtitle.PresentTime + currentSubtitle.TimeOut)
      {
        currentSubtitle.ShouldDraw = true;
        return;
      }

      // If we have already a sub in queue, wait until it's time to show
      if (currentSubtitle != null && currentSubtitle.PresentTime > currentTime)
      {
        currentSubtitle.ShouldDraw = false;
        return;
      }

      // Check for waiting subs
      lock (_syncObj)
      {
        while (_subtitles.Count > 0)
        {
          Subtitle next = _subtitles.First.Value;
          // if the next should be displayed now or previously
          if (next.PresentTime <= currentTime)
          {
            // remove from queue
            _subtitles.RemoveFirst();

            // if it is not too late for this sub to be displayed, break
            if (next.PresentTime + next.TimeOut >= currentTime)
            {
              next.ShouldDraw = true;
              SetSubtitle(next);
              return;
            }
          }
          else
            break;
        }
      }
      if (currentSubtitle != null)
        SetSubtitle(null);
    }
    // Currently unused, teletext subtitles are not yet (re-)implemented!
    public void OnTextSubtitle(ref TextSubtitle sub)
    {
      ServiceRegistration.Get<ILogger>().Debug("On TextSubtitle called");
      try
      {
        if (sub.Page == _activeSubPage)
        {
          ServiceRegistration.Get<ILogger>().Debug("Page: " + sub.Page);
          ServiceRegistration.Get<ILogger>().Debug("Character table: " + sub.Encoding);
          ServiceRegistration.Get<ILogger>().Debug("Timeout: " + sub.TimeOut);
          ServiceRegistration.Get<ILogger>().Debug("Timestamp" + sub.TimeStamp);
          ServiceRegistration.Get<ILogger>().Debug("Language: " + sub.Language);

          String content = sub.Text;
          if (content == null)
          {
            ServiceRegistration.Get<ILogger>().Error("OnTextSubtitle: sub.txt == null!");
            return;
          }
        }
      }
      catch (Exception e)
      {
        ServiceRegistration.Get<ILogger>().Error("Problem with TEXT_SUBTITLE");
        ServiceRegistration.Get<ILogger>().Error(e);
      }

      try
      {
        // if we dont need the subtitle
        if (!_renderSubtitles || _useBitmap || (_activeSubPage != sub.Page))
        {
          ServiceRegistration.Get<ILogger>().Debug("Text subtitle (page {0}) discarded: useBitmap is {1} and activeSubPage is {2}", sub.Page, _useBitmap, _activeSubPage);
          return;
        }
        ServiceRegistration.Get<ILogger>().Debug("Text subtitle (page {0}) ACCEPTED: useBitmap is {1} and activeSubPage is {2}", sub.Page, _useBitmap, _activeSubPage);

        Subtitle subtitle = new Subtitle
                              {
                                SubBitmap = RenderText(sub.LineContents),
                                TimeOut = sub.TimeOut,
                                PresentTime = sub.TimeStamp / 90000.0f + _startPos,
                                Height = (uint) SkinContext.SkinResources.SkinHeight,
                                Width = (uint) SkinContext.SkinResources.SkinWidth,
                                FirstScanLine = 0
                              };

        lock (_subtitles)
        {
          while (_subtitles.Count >= MAX_SUBTITLES_IN_QUEUE)
          {
            ServiceRegistration.Get<ILogger>().Debug("SubtitleRenderer: Subtitle queue too big, discarding first element");
            _subtitles.RemoveFirst();
          }
          _subtitles.AddLast(subtitle);

          ServiceRegistration.Get<ILogger>().Debug("SubtitleRenderer: Text subtitle added, now have {0} subtitles in cache {1} pos on last render was {2}", _subtitles.Count, subtitle, _currentTime);
        }
      }
      catch (Exception e)
      {
        ServiceRegistration.Get<ILogger>().Error("Problem processing text subtitle");
        ServiceRegistration.Get<ILogger>().Error(e);
      }
    }
 protected virtual Subtitle ToSubtitle(IntPtr nativeSubPtr)
 {
   NativeSubtitle nativeSub = (NativeSubtitle) Marshal.PtrToStructure(nativeSubPtr, typeof(NativeSubtitle));
   Subtitle subtitle = new Subtitle
   {
     SubBitmap = new Bitmap(nativeSub.Width, nativeSub.Height, PixelFormat.Format32bppArgb),
     TimeOut = nativeSub.TimeOut,
     PresentTime = ((double) nativeSub.TimeStamp / 1000.0f) + _startPos,
     Height = (uint) nativeSub.Height,
     Width = (uint) nativeSub.Width,
     ScreenWidth = nativeSub.ScreenWidth,
     FirstScanLine = nativeSub.FirstScanLine,
     Id = _subCounter++
   };
   CopyBits(nativeSub.Bits, ref subtitle.SubBitmap, nativeSub.Width, nativeSub.Height, nativeSub.WidthBytes);
   return subtitle;
 }
Example #5
0
        // Currently unused, teletext subtitles are not yet (re-)implemented!
        public void OnTextSubtitle(ref TextSubtitle sub)
        {
            ServiceRegistration.Get <ILogger>().Debug("On TextSubtitle called");
            try
            {
                if (sub.Page == _activeSubPage)
                {
                    ServiceRegistration.Get <ILogger>().Debug("Page: " + sub.Page);
                    ServiceRegistration.Get <ILogger>().Debug("Character table: " + sub.Encoding);
                    ServiceRegistration.Get <ILogger>().Debug("Timeout: " + sub.TimeOut);
                    ServiceRegistration.Get <ILogger>().Debug("Timestamp" + sub.TimeStamp);
                    ServiceRegistration.Get <ILogger>().Debug("Language: " + sub.Language);

                    String content = sub.Text;
                    if (content == null)
                    {
                        ServiceRegistration.Get <ILogger>().Error("OnTextSubtitle: sub.txt == null!");
                        return;
                    }
                }
            }
            catch (Exception e)
            {
                ServiceRegistration.Get <ILogger>().Error("Problem with TEXT_SUBTITLE");
                ServiceRegistration.Get <ILogger>().Error(e);
            }

            try
            {
                // if we dont need the subtitle
                if (!_renderSubtitles || _useBitmap || (_activeSubPage != sub.Page))
                {
                    ServiceRegistration.Get <ILogger>().Debug("Text subtitle (page {0}) discarded: useBitmap is {1} and activeSubPage is {2}", sub.Page, _useBitmap, _activeSubPage);
                    return;
                }
                ServiceRegistration.Get <ILogger>().Debug("Text subtitle (page {0}) ACCEPTED: useBitmap is {1} and activeSubPage is {2}", sub.Page, _useBitmap, _activeSubPage);

                Subtitle subtitle = new Subtitle(_device)
                {
                    SubBitmap     = RenderText(sub.LineContents),
                    TimeOut       = sub.TimeOut,
                    PresentTime   = sub.TimeStamp / 90000.0f + _startPos,
                    Height        = (uint)SkinContext.SkinResources.SkinHeight,
                    Width         = (uint)SkinContext.SkinResources.SkinWidth,
                    FirstScanLine = 0
                };

                lock (_subtitles)
                {
                    while (_subtitles.Count >= MAX_SUBTITLES_IN_QUEUE)
                    {
                        ServiceRegistration.Get <ILogger>().Debug("SubtitleRenderer: Subtitle queue too big, discarding first element");
                        _subtitles.RemoveFirst();
                    }
                    _subtitles.AddLast(subtitle);

                    ServiceRegistration.Get <ILogger>().Debug("SubtitleRenderer: Text subtitle added, now have {0} subtitles in cache {1} pos on last render was {2}", _subtitles.Count, subtitle, _currentTime);
                }
            }
            catch (Exception e)
            {
                ServiceRegistration.Get <ILogger>().Error("Problem processing text subtitle");
                ServiceRegistration.Get <ILogger>().Error(e);
            }
        }