tdesktop/Telegram/SourceFiles/media/streaming/media_streaming_audio_track.h

96 lines
2.6 KiB
C
Raw Normal View History

/*
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 "base/observer.h"
#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(
const PlaybackOptions &options,
Stream &&stream,
2019-02-21 11:15:44 +00:00
AudioMsgId audioId,
FnMut<void(const Information &)> ready,
2019-03-05 13:56:27 +00:00
Fn<void(Error)> error);
// 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);
// 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);
[[nodiscard]] rpl::producer<> waitingForData() const;
2019-02-21 16:01:55 +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.
[[nodiscard]] rpl::producer<crl::time> playPosition();
// Thread-safe.
[[nodiscard]] int streamIndex() const;
[[nodiscard]] AVRational streamTimeBase() const;
[[nodiscard]] crl::time streamDuration() const;
// Called from the same unspecified thread.
void process(std::vector<FFmpeg::Packet> &&packets);
void waitForData();
// 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);
[[nodiscard]] bool fillStateFromFrame();
2019-02-22 12:39:32 +00:00
[[nodiscard]] bool processFirstFrame();
void mixerInit();
void mixerEnqueue(gsl::span<FFmpeg::Packet> packets);
void mixerForceToBuffer();
void callReady();
2019-02-21 16:01:55 +00:00
PlaybackOptions _options;
// Accessed from the same unspecified thread.
Stream _stream;
2019-02-21 11:15:44 +00:00
const AudioMsgId _audioId;
bool _readTillEnd = false;
// Assumed to be thread-safe.
FnMut<void(const Information &)> _ready;
2019-03-05 13:56:27 +00:00
const Fn<void(Error)> _error;
// First set from the same unspecified thread before _ready is called.
// After that is immutable.
crl::time _startedPosition = kTimeUnknown;
// Accessed from the main thread.
base::Subscription _subscription;
rpl::event_stream<> _waitingForData;
// First set from the same unspecified thread before _ready is called.
// After that accessed from the main thread.
rpl::variable<crl::time> _playPosition;
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
};
} // namespace Streaming
} // namespace Media