/// <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; }
// 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); } }