media_streaming_audio_track.h 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #pragma once
  8. #include "media/streaming/media_streaming_utility.h"
  9. namespace Media {
  10. namespace Streaming {
  11. class AudioTrack final {
  12. public:
  13. // Called from some unspecified thread.
  14. // Callbacks are assumed to be thread-safe.
  15. AudioTrack(
  16. const PlaybackOptions &options,
  17. Stream &&stream,
  18. AudioMsgId audioId,
  19. FnMut<void(const Information &)> ready,
  20. Fn<void(Error)> error);
  21. // Called from the main thread.
  22. // Must be called after 'ready' was invoked.
  23. void pause(crl::time time);
  24. void resume(crl::time time);
  25. // Allow to irreversibly stop only audio track.
  26. void stop();
  27. // Called from the main thread.
  28. void setSpeed(float64 speed);
  29. [[nodiscard]] rpl::producer<> waitingForData() const;
  30. // Called from the main thread.
  31. // Non-const, because we subscribe to changes on the first call.
  32. // Must be called after 'ready' was invoked.
  33. [[nodiscard]] rpl::producer<crl::time> playPosition();
  34. // Thread-safe.
  35. [[nodiscard]] int streamIndex() const;
  36. [[nodiscard]] AVRational streamTimeBase() const;
  37. [[nodiscard]] crl::time streamDuration() const;
  38. // Called from the same unspecified thread.
  39. void process(std::vector<FFmpeg::Packet> &&packets);
  40. void waitForData();
  41. // Called from the main thread.
  42. ~AudioTrack();
  43. private:
  44. // Called from the same unspecified thread.
  45. [[nodiscard]] bool initialized() const;
  46. [[nodiscard]] bool tryReadFirstFrame(FFmpeg::Packet &&packet);
  47. [[nodiscard]] bool fillStateFromFrame();
  48. [[nodiscard]] bool processFirstFrame();
  49. void mixerInit();
  50. void mixerEnqueue(gsl::span<FFmpeg::Packet> packets);
  51. void mixerForceToBuffer();
  52. void callReady();
  53. PlaybackOptions _options;
  54. // Accessed from the same unspecified thread.
  55. Stream _stream;
  56. const AudioMsgId _audioId;
  57. bool _readTillEnd = false;
  58. // Assumed to be thread-safe.
  59. FnMut<void(const Information &)> _ready;
  60. const Fn<void(Error)> _error;
  61. // First set from the same unspecified thread before _ready is called.
  62. // After that is immutable.
  63. crl::time _startedPosition = kTimeUnknown;
  64. // Accessed from the main thread.
  65. rpl::lifetime _subscription;
  66. rpl::event_stream<> _waitingForData;
  67. // First set from the same unspecified thread before _ready is called.
  68. // After that accessed from the main thread.
  69. rpl::variable<crl::time> _playPosition;
  70. // For initial frame skipping for an exact seek.
  71. FFmpeg::FramePointer _initialSkippingFrame;
  72. };
  73. } // namespace Streaming
  74. } // namespace Media