media_streaming_file.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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_common.h"
  9. #include "media/streaming/media_streaming_utility.h"
  10. #include "media/streaming/media_streaming_reader.h"
  11. #include "ffmpeg/ffmpeg_utility.h"
  12. #include "base/bytes.h"
  13. #include "base/weak_ptr.h"
  14. #include <thread>
  15. namespace Media {
  16. namespace Streaming {
  17. class FileDelegate;
  18. struct StartOptions {
  19. crl::time position = 0;
  20. crl::time durationOverride = 0;
  21. bool seekable = true;
  22. bool hwAllow = false;
  23. };
  24. class File final {
  25. public:
  26. explicit File(std::shared_ptr<Reader> reader);
  27. File(const File &other) = delete;
  28. File &operator=(const File &other) = delete;
  29. void start(not_null<FileDelegate*> delegate, StartOptions options);
  30. void wake();
  31. void stop(bool stillActive = false);
  32. [[nodiscard]] bool isRemoteLoader() const;
  33. void setLoaderPriority(int priority);
  34. [[nodiscard]] int64 size() const;
  35. [[nodiscard]] rpl::producer<SpeedEstimate> speedEstimate() const;
  36. ~File();
  37. private:
  38. class Context final : public base::has_weak_ptr {
  39. public:
  40. Context(not_null<FileDelegate*> delegate, not_null<Reader*> reader);
  41. ~Context();
  42. void start(StartOptions options);
  43. void readNextPacket();
  44. void interrupt();
  45. void wake();
  46. [[nodiscard]] bool interrupted() const;
  47. [[nodiscard]] bool failed() const;
  48. [[nodiscard]] bool finished() const;
  49. void stopStreamingAsync();
  50. private:
  51. enum class SleepPolicy {
  52. Allowed,
  53. Disallowed,
  54. };
  55. static int Read(void *opaque, uint8_t *buffer, int bufferSize);
  56. static int64_t Seek(void *opaque, int64_t offset, int whence);
  57. [[nodiscard]] int read(bytes::span buffer);
  58. [[nodiscard]] int64_t seek(int64_t offset, int whence);
  59. [[nodiscard]] bool unroll() const;
  60. void logError(QLatin1String method);
  61. void logError(QLatin1String method, FFmpeg::AvErrorWrap error);
  62. void logFatal(QLatin1String method);
  63. void logFatal(QLatin1String method, FFmpeg::AvErrorWrap error);
  64. void fail(Error error);
  65. [[nodiscard]] Stream initStream(
  66. not_null<AVFormatContext *> format,
  67. AVMediaType type,
  68. Mode mode,
  69. StartOptions options);
  70. void seekToPosition(
  71. not_null<AVFormatContext *> format,
  72. const Stream &stream,
  73. crl::time position);
  74. // TODO base::expected.
  75. [[nodiscard]] auto readPacket()
  76. -> std::variant<FFmpeg::Packet, FFmpeg::AvErrorWrap>;
  77. void processQueuedPackets(SleepPolicy policy);
  78. void handleEndOfFile();
  79. void sendFullInCache(bool force = false);
  80. const not_null<FileDelegate*> _delegate;
  81. const not_null<Reader*> _reader;
  82. base::flat_map<int, std::vector<FFmpeg::Packet>> _queuedPackets;
  83. int64 _offset = 0;
  84. int64 _size = 0;
  85. bool _failed = false;
  86. bool _readTillEnd = false;
  87. std::optional<bool> _fullInCache;
  88. crl::semaphore _semaphore;
  89. std::atomic<bool> _interrupted = false;
  90. FFmpeg::FormatPointer _format;
  91. };
  92. std::optional<Context> _context;
  93. std::shared_ptr<Reader> _reader;
  94. std::thread _thread;
  95. };
  96. } // namespace Streaming
  97. } // namespace Media