Files
platform-external-webrtc/video/video_stream_decoder_impl.h
philipel 539f9b376e Use a TaskQueue for decoding in VideoStreamDecoderImpl.
Long term goal is to use the VideoStreamDecoder in the VideoReceiveStream so
that we can stop using legacy VideoCodingModule components and classes. This CL is
one of several in preparation for that.

Bug: webrtc:7408, webrtc:9378
Change-Id: Ifd7e4c3c7d38dbb7c4b0636aaad318c571a29158
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/164525
Reviewed-by: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Åsa Persson <asapersson@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Commit-Queue: Philip Eliasson <philipel@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30211}
2020-01-10 14:31:22 +00:00

126 lines
4.8 KiB
C++

/*
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef VIDEO_VIDEO_STREAM_DECODER_IMPL_H_
#define VIDEO_VIDEO_STREAM_DECODER_IMPL_H_
#include <map>
#include <memory>
#include <utility>
#include "absl/types/optional.h"
#include "api/video/video_stream_decoder.h"
#include "modules/video_coding/frame_buffer2.h"
#include "modules/video_coding/timing.h"
#include "rtc_base/platform_thread.h"
#include "rtc_base/task_queue.h"
#include "rtc_base/thread_checker.h"
#include "system_wrappers/include/clock.h"
namespace webrtc {
class VideoStreamDecoderImpl : public VideoStreamDecoderInterface {
public:
VideoStreamDecoderImpl(
VideoStreamDecoderInterface::Callbacks* callbacks,
VideoDecoderFactory* decoder_factory,
TaskQueueFactory* task_queue_factory,
std::map<int, std::pair<SdpVideoFormat, int>> decoder_settings);
~VideoStreamDecoderImpl() override;
void OnFrame(std::unique_ptr<video_coding::EncodedFrame> frame) override;
void SetMinPlayoutDelay(TimeDelta min_delay) override;
void SetMaxPlayoutDelay(TimeDelta max_delay) override;
private:
class DecodeCallbacks : public DecodedImageCallback {
public:
explicit DecodeCallbacks(VideoStreamDecoderImpl* video_stream_decoder_impl);
int32_t Decoded(VideoFrame& decodedImage) override;
int32_t Decoded(VideoFrame& decodedImage, int64_t decode_time_ms) override;
void Decoded(VideoFrame& decodedImage,
absl::optional<int32_t> decode_time_ms,
absl::optional<uint8_t> qp) override;
private:
VideoStreamDecoderImpl* const video_stream_decoder_impl_;
};
enum DecodeResult {
kOk,
kOkRequestKeyframe,
kDecodeFailure,
};
struct FrameTimestamps {
int64_t timestamp;
int64_t decode_start_time_ms;
int64_t render_time_us;
};
void SaveFrameTimestamps(const video_coding::EncodedFrame& frame)
RTC_RUN_ON(bookkeeping_queue_);
FrameTimestamps* GetFrameTimestamps(int64_t timestamp)
RTC_RUN_ON(bookkeeping_queue_);
void StartNextDecode() RTC_RUN_ON(bookkeeping_queue_);
void OnNextFrameCallback(std::unique_ptr<video_coding::EncodedFrame> frame,
video_coding::FrameBuffer::ReturnReason res)
RTC_RUN_ON(bookkeeping_queue_);
void OnDecodedFrameCallback(VideoFrame& decodedImage, // NOLINT
absl::optional<int32_t> decode_time_ms,
absl::optional<uint8_t> qp);
VideoDecoder* GetDecoder(int payload_type) RTC_RUN_ON(decode_queue_);
VideoStreamDecoderImpl::DecodeResult DecodeFrame(
std::unique_ptr<video_coding::EncodedFrame> frame)
RTC_RUN_ON(decode_queue_);
VCMTiming timing_;
DecodeCallbacks decode_callbacks_;
// Some decoders are pipelined so it is not sufficient to save frame info
// for the last frame only.
static constexpr int kFrameTimestampsMemory = 8;
std::array<FrameTimestamps, kFrameTimestampsMemory> frame_timestamps_
RTC_GUARDED_BY(bookkeeping_queue_);
int next_frame_timestamps_index_ RTC_GUARDED_BY(bookkeeping_queue_);
VideoStreamDecoderInterface::Callbacks* const callbacks_
RTC_PT_GUARDED_BY(bookkeeping_queue_);
video_coding::VideoLayerFrameId last_continuous_id_
RTC_GUARDED_BY(bookkeeping_queue_);
bool keyframe_required_ RTC_GUARDED_BY(bookkeeping_queue_);
absl::optional<int> current_payload_type_ RTC_GUARDED_BY(decode_queue_);
VideoDecoderFactory* const decoder_factory_ RTC_PT_GUARDED_BY(decode_queue_);
std::map<int, std::pair<SdpVideoFormat, int>> decoder_settings_
RTC_GUARDED_BY(decode_queue_);
// The |bookkeeping_queue_| use the |frame_buffer_| and also posts tasks to
// the |decode_queue_|. The |decode_queue_| in turn use the |decoder_| to
// decode frames. When the |decoder_| is done it will post back to the
// |bookkeeping_queue_| with the decoded frame. During shutdown we start by
// isolating the |bookkeeping_queue_| from the |decode_queue_|, so now it's
// safe for the |decode_queue_| to be destructed. After that the |decoder_|
// can be destructed, and then the |bookkeeping_queue_|. Finally the
// |frame_buffer_| can be destructed.
rtc::CriticalSection shut_down_crit_;
bool shut_down_ RTC_GUARDED_BY(shut_down_crit_);
video_coding::FrameBuffer frame_buffer_ RTC_GUARDED_BY(bookkeeping_queue_);
rtc::TaskQueue bookkeeping_queue_;
std::unique_ptr<VideoDecoder> decoder_ RTC_GUARDED_BY(decode_queue_);
rtc::TaskQueue decode_queue_;
};
} // namespace webrtc
#endif // VIDEO_VIDEO_STREAM_DECODER_IMPL_H_