VideoStreamDecoderImpl implementation, part 1.

In this CL the OnFrame function is implemented.

Bug: webrtc:8909
Change-Id: I68488a033e86eadd0b16d091faad14e9cda7cc36
Reviewed-on: https://webrtc-review.googlesource.com/64121
Reviewed-by: Niels Moller <nisse@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Commit-Queue: Philip Eliasson <philipel@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22583}
This commit is contained in:
philipel 2018-03-23 10:43:21 +01:00 committed by Commit Bot
parent a9d988d175
commit 9718711dee
6 changed files with 72 additions and 17 deletions

View File

@ -21,10 +21,6 @@
#include "api/video_codecs/video_decoder_factory.h"
namespace webrtc {
// TODO(philipel): #include instead of forward declare when the relevant CL has
// landed.
class FrameKey;
// NOTE: This class is still under development and may change without notice.
class VideoStreamDecoder {
public:
@ -36,7 +32,8 @@ class VideoStreamDecoder {
virtual void OnNonDecodableState() = 0;
// Called with the last continuous frame.
virtual void OnContinuousUntil(const FrameKey& key) = 0;
virtual void OnContinuousUntil(
const video_coding::VideoLayerFrameId& key) = 0;
// Called with the decoded frame.
virtual void OnDecodedFrame(VideoFrame decodedImage,

View File

@ -588,7 +588,7 @@ void FrameBuffer::UpdateJitterDelay() {
void FrameBuffer::UpdateTimingFrameInfo() {
TRACE_EVENT0("webrtc", "FrameBuffer::UpdateTimingFrameInfo");
rtc::Optional<TimingFrameInfo> info = timing_->GetTimingFrameInfo();
if (info)
if (info && stats_callback_)
stats_callback_->OnTimingFrameInfoUpdated(*info);
}

View File

@ -47,6 +47,7 @@ class FrameBuffer {
// Insert a frame into the frame buffer. Returns the picture id
// of the last continuous frame or -1 if there is no continuous frame.
// TODO(philipel): Return a VideoLayerFrameId and not only the picture id.
int64_t InsertFrame(std::unique_ptr<EncodedFrame> frame);
// Get the next frame for decoding. Will return at latest after

View File

@ -116,7 +116,10 @@ rtc_source_set("video_stream_decoder_impl") {
"../api:video_frame_api",
"../api:video_stream_decoder",
"../api/video_codecs:video_codecs_api",
"../modules/video_coding:video_coding",
"../rtc_base:rtc_base_approved",
"../rtc_base:rtc_task_queue_api",
"../system_wrappers:system_wrappers",
]
if (!build_with_chromium && is_clang) {

View File

@ -10,19 +10,61 @@
#include "video/video_stream_decoder_impl.h"
#include "rtc_base/logging.h"
#include "rtc_base/ptr_util.h"
namespace webrtc {
VideoStreamDecoderImpl::VideoStreamDecoderImpl(
VideoStreamDecoder::Callbacks* callbacks,
VideoDecoderFactory* decoder_factory,
std::map<int, std::pair<SdpVideoFormat, int>> decoder_settings)
: callbacks_(callbacks),
decoder_factory_(decoder_factory),
decoder_settings_(std::move(decoder_settings)) {}
decoder_settings_(std::move(decoder_settings)),
bookkeeping_queue_("video_stream_decoder_bookkeeping_queue"),
jitter_estimator_(Clock::GetRealTimeClock()),
timing_(Clock::GetRealTimeClock()),
frame_buffer_(Clock::GetRealTimeClock(),
&jitter_estimator_,
&timing_,
nullptr) {}
VideoStreamDecoderImpl::~VideoStreamDecoderImpl() {}
VideoStreamDecoderImpl::~VideoStreamDecoderImpl() {
frame_buffer_.Stop();
}
void VideoStreamDecoderImpl::OnFrame(
std::unique_ptr<video_coding::EncodedFrame> frame) {}
std::unique_ptr<video_coding::EncodedFrame> frame) {
if (!bookkeeping_queue_.IsCurrent()) {
struct OnFrameTask : rtc::QueuedTask {
OnFrameTask(std::unique_ptr<video_coding::EncodedFrame> frame,
VideoStreamDecoderImpl* video_stream_decoder)
: frame_(std::move(frame)),
video_stream_decoder_(video_stream_decoder) {}
bool Run() {
video_stream_decoder_->OnFrame(std::move(frame_));
return true;
}
std::unique_ptr<video_coding::EncodedFrame> frame_;
VideoStreamDecoderImpl* video_stream_decoder_;
};
bookkeeping_queue_.PostTask(
rtc::MakeUnique<OnFrameTask>(std::move(frame), this));
return;
}
RTC_DCHECK_RUN_ON(&bookkeeping_queue_);
uint64_t continuous_pid = frame_buffer_.InsertFrame(std::move(frame));
video_coding::VideoLayerFrameId continuous_id(continuous_pid, 0);
if (last_continuous_id_ < continuous_id) {
last_continuous_id_ = continuous_id;
callbacks_->OnContinuousUntil(last_continuous_id_);
}
}
} // namespace webrtc

View File

@ -11,17 +11,17 @@
#ifndef VIDEO_VIDEO_STREAM_DECODER_IMPL_H_
#define VIDEO_VIDEO_STREAM_DECODER_IMPL_H_
#include <functional>
#include <map>
#include <memory>
#include <utility>
#include "api/optional.h"
#include "api/video/encoded_frame.h"
#include "api/video/video_frame.h"
#include "api/video/video_stream_decoder.h"
#include "api/video_codecs/sdp_video_format.h"
#include "api/video_codecs/video_decoder_factory.h"
#include "modules/video_coding/frame_buffer2.h"
#include "modules/video_coding/jitter_estimator.h"
#include "modules/video_coding/timing.h"
#include "rtc_base/task_queue.h"
#include "rtc_base/thread_checker.h"
#include "system_wrappers/include/clock.h"
namespace webrtc {
@ -45,9 +45,21 @@ class VideoStreamDecoderImpl : public VideoStreamDecoder,
rtc::Optional<int32_t> decode_time_ms,
rtc::Optional<uint8_t> qp) override;
VideoStreamDecoder::Callbacks* callbacks_;
VideoDecoderFactory* decoder_factory_;
VideoStreamDecoder::Callbacks* const callbacks_
RTC_PT_GUARDED_BY(bookkeeping_queue_);
VideoDecoderFactory* const decoder_factory_;
std::map<int, std::pair<SdpVideoFormat, int>> decoder_settings_;
// The |bookkeeping_queue_| is used to:
// - Make |callbacks_|.
// - Insert/extract frames from the |frame_buffer_|
// - Synchronize with whatever thread that makes the Decoded callback.
rtc::TaskQueue bookkeeping_queue_;
VCMJitterEstimator jitter_estimator_;
VCMTiming timing_;
video_coding::FrameBuffer frame_buffer_;
video_coding::VideoLayerFrameId last_continuous_id_;
};
} // namespace webrtc