| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- /*
- This file is part of Telegram Desktop,
- the official desktop application for the Telegram messaging service.
- For license and copyright information please follow this link:
- https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
- */
- #pragma once
- #include "media/streaming/media_streaming_common.h"
- #include "media/streaming/media_streaming_utility.h"
- #include "media/streaming/media_streaming_reader.h"
- #include "ffmpeg/ffmpeg_utility.h"
- #include "base/bytes.h"
- #include "base/weak_ptr.h"
- #include <thread>
- namespace Media {
- namespace Streaming {
- class FileDelegate;
- struct StartOptions {
- crl::time position = 0;
- crl::time durationOverride = 0;
- bool seekable = true;
- bool hwAllow = false;
- };
- class File final {
- public:
- explicit File(std::shared_ptr<Reader> reader);
- File(const File &other) = delete;
- File &operator=(const File &other) = delete;
- void start(not_null<FileDelegate*> delegate, StartOptions options);
- void wake();
- void stop(bool stillActive = false);
- [[nodiscard]] bool isRemoteLoader() const;
- void setLoaderPriority(int priority);
- [[nodiscard]] int64 size() const;
- [[nodiscard]] rpl::producer<SpeedEstimate> speedEstimate() const;
- ~File();
- private:
- class Context final : public base::has_weak_ptr {
- public:
- Context(not_null<FileDelegate*> delegate, not_null<Reader*> reader);
- ~Context();
- void start(StartOptions options);
- void readNextPacket();
- void interrupt();
- void wake();
- [[nodiscard]] bool interrupted() const;
- [[nodiscard]] bool failed() const;
- [[nodiscard]] bool finished() const;
- void stopStreamingAsync();
- private:
- enum class SleepPolicy {
- Allowed,
- Disallowed,
- };
- static int Read(void *opaque, uint8_t *buffer, int bufferSize);
- static int64_t Seek(void *opaque, int64_t offset, int whence);
- [[nodiscard]] int read(bytes::span buffer);
- [[nodiscard]] int64_t seek(int64_t offset, int whence);
- [[nodiscard]] bool unroll() const;
- void logError(QLatin1String method);
- void logError(QLatin1String method, FFmpeg::AvErrorWrap error);
- void logFatal(QLatin1String method);
- void logFatal(QLatin1String method, FFmpeg::AvErrorWrap error);
- void fail(Error error);
- [[nodiscard]] Stream initStream(
- not_null<AVFormatContext *> format,
- AVMediaType type,
- Mode mode,
- StartOptions options);
- void seekToPosition(
- not_null<AVFormatContext *> format,
- const Stream &stream,
- crl::time position);
- // TODO base::expected.
- [[nodiscard]] auto readPacket()
- -> std::variant<FFmpeg::Packet, FFmpeg::AvErrorWrap>;
- void processQueuedPackets(SleepPolicy policy);
- void handleEndOfFile();
- void sendFullInCache(bool force = false);
- const not_null<FileDelegate*> _delegate;
- const not_null<Reader*> _reader;
- base::flat_map<int, std::vector<FFmpeg::Packet>> _queuedPackets;
- int64 _offset = 0;
- int64 _size = 0;
- bool _failed = false;
- bool _readTillEnd = false;
- std::optional<bool> _fullInCache;
- crl::semaphore _semaphore;
- std::atomic<bool> _interrupted = false;
- FFmpeg::FormatPointer _format;
- };
- std::optional<Context> _context;
- std::shared_ptr<Reader> _reader;
- std::thread _thread;
- };
- } // namespace Streaming
- } // namespace Media
|