2019-02-17 11:08:29 +00:00
|
|
|
/*
|
|
|
|
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_utility.h"
|
|
|
|
|
|
|
|
namespace Media {
|
|
|
|
namespace Streaming {
|
|
|
|
|
|
|
|
class AudioTrack final {
|
|
|
|
public:
|
|
|
|
// Called from some unspecified thread.
|
|
|
|
// Callbacks are assumed to be thread-safe.
|
|
|
|
AudioTrack(
|
2019-02-21 09:17:25 +00:00
|
|
|
const PlaybackOptions &options,
|
2019-02-17 11:08:29 +00:00
|
|
|
Stream &&stream,
|
2019-02-21 11:15:44 +00:00
|
|
|
AudioMsgId audioId,
|
2019-02-17 11:08:29 +00:00
|
|
|
FnMut<void(const Information &)> ready,
|
2019-03-05 13:56:27 +00:00
|
|
|
Fn<void(Error)> error);
|
2019-02-17 11:08:29 +00:00
|
|
|
|
|
|
|
// Called from the main thread.
|
|
|
|
// Must be called after 'ready' was invoked.
|
2019-02-21 14:57:00 +00:00
|
|
|
void pause(crl::time time);
|
|
|
|
void resume(crl::time time);
|
2019-02-17 11:08:29 +00:00
|
|
|
|
2019-12-18 18:26:17 +00:00
|
|
|
// Allow to irreversibly stop only audio track.
|
|
|
|
void stop();
|
|
|
|
|
2019-02-21 16:01:55 +00:00
|
|
|
// Called from the main thread.
|
|
|
|
void setSpeed(float64 speed);
|
2019-02-22 14:28:10 +00:00
|
|
|
[[nodiscard]] rpl::producer<> waitingForData() const;
|
2019-02-21 16:01:55 +00:00
|
|
|
|
2019-02-17 11:08:29 +00:00
|
|
|
// Called from the main thread.
|
|
|
|
// Non-const, because we subscribe to changes on the first call.
|
|
|
|
// Must be called after 'ready' was invoked.
|
2019-02-20 13:28:48 +00:00
|
|
|
[[nodiscard]] rpl::producer<crl::time> playPosition();
|
2019-02-17 11:08:29 +00:00
|
|
|
|
|
|
|
// Thread-safe.
|
|
|
|
[[nodiscard]] int streamIndex() const;
|
|
|
|
[[nodiscard]] AVRational streamTimeBase() const;
|
2019-03-05 07:40:25 +00:00
|
|
|
[[nodiscard]] crl::time streamDuration() const;
|
2019-02-17 11:08:29 +00:00
|
|
|
|
|
|
|
// Called from the same unspecified thread.
|
2019-12-19 15:14:05 +00:00
|
|
|
void process(std::vector<FFmpeg::Packet> &&packets);
|
2019-02-21 13:40:09 +00:00
|
|
|
void waitForData();
|
2019-02-17 11:08:29 +00:00
|
|
|
|
|
|
|
// Called from the main thread.
|
|
|
|
~AudioTrack();
|
|
|
|
|
|
|
|
private:
|
|
|
|
// Called from the same unspecified thread.
|
2019-02-21 11:15:44 +00:00
|
|
|
[[nodiscard]] bool initialized() const;
|
2019-06-26 15:04:38 +00:00
|
|
|
[[nodiscard]] bool tryReadFirstFrame(FFmpeg::Packet &&packet);
|
2019-02-17 11:08:29 +00:00
|
|
|
[[nodiscard]] bool fillStateFromFrame();
|
2019-02-22 12:39:32 +00:00
|
|
|
[[nodiscard]] bool processFirstFrame();
|
2019-02-17 11:08:29 +00:00
|
|
|
void mixerInit();
|
2019-12-19 15:14:05 +00:00
|
|
|
void mixerEnqueue(gsl::span<FFmpeg::Packet> packets);
|
2019-02-21 13:40:09 +00:00
|
|
|
void mixerForceToBuffer();
|
2019-02-17 11:08:29 +00:00
|
|
|
void callReady();
|
|
|
|
|
2019-02-21 16:01:55 +00:00
|
|
|
PlaybackOptions _options;
|
2019-02-21 09:17:25 +00:00
|
|
|
|
2019-02-17 11:08:29 +00:00
|
|
|
// Accessed from the same unspecified thread.
|
|
|
|
Stream _stream;
|
2019-02-21 11:15:44 +00:00
|
|
|
const AudioMsgId _audioId;
|
2019-03-13 14:58:50 +00:00
|
|
|
bool _readTillEnd = false;
|
2019-02-17 11:08:29 +00:00
|
|
|
|
|
|
|
// Assumed to be thread-safe.
|
|
|
|
FnMut<void(const Information &)> _ready;
|
2019-03-05 13:56:27 +00:00
|
|
|
const Fn<void(Error)> _error;
|
2019-02-17 11:08:29 +00:00
|
|
|
|
|
|
|
// First set from the same unspecified thread before _ready is called.
|
|
|
|
// After that is immutable.
|
2019-02-20 13:28:48 +00:00
|
|
|
crl::time _startedPosition = kTimeUnknown;
|
2019-02-17 11:08:29 +00:00
|
|
|
|
|
|
|
// Accessed from the main thread.
|
|
|
|
base::Subscription _subscription;
|
2019-02-22 14:28:10 +00:00
|
|
|
rpl::event_stream<> _waitingForData;
|
2019-02-21 11:51:22 +00:00
|
|
|
// First set from the same unspecified thread before _ready is called.
|
|
|
|
// After that accessed from the main thread.
|
2019-02-20 13:28:48 +00:00
|
|
|
rpl::variable<crl::time> _playPosition;
|
2019-02-17 11:08:29 +00:00
|
|
|
|
2019-02-22 12:39:32 +00:00
|
|
|
// For initial frame skipping for an exact seek.
|
2019-06-26 15:04:38 +00:00
|
|
|
FFmpeg::FramePointer _initialSkippingFrame;
|
2019-02-22 12:39:32 +00:00
|
|
|
|
2019-02-17 11:08:29 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace Streaming
|
|
|
|
} // namespace Media
|