webrtc/modules/video_coding/generic_decoder.h
Ilya Nikolaevskiy 2ebf523978 Reland "Copy video frames metadata between encoded and plain frames in one place"
Reland with fixes.

Currently some video frames metadata like rotation or ntp timestamps are
copied in every encoder and decoder separately. This CL makes copying to
happen at a single place for send or receive side. This will make it
easier to add new metadata in the future.

Also, added some missing tests.

Original Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/133346

Bug: webrtc:10460
Change-Id: I98629589fa55ca1d74056033cf86faccfdf848cd
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/136582
Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27930}
2019-05-13 14:51:11 +00:00

115 lines
3.7 KiB
C++

/*
* Copyright (c) 2012 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 MODULES_VIDEO_CODING_GENERIC_DECODER_H_
#define MODULES_VIDEO_CODING_GENERIC_DECODER_H_
#include <memory>
#include "modules/include/module_common_types.h"
#include "modules/video_coding/encoded_frame.h"
#include "modules/video_coding/include/video_codec_interface.h"
#include "modules/video_coding/timestamp_map.h"
#include "modules/video_coding/timing.h"
#include "rtc_base/critical_section.h"
#include "rtc_base/thread_checker.h"
namespace webrtc {
class VCMReceiveCallback;
enum { kDecoderFrameMemoryLength = 10 };
struct VCMFrameInformation {
int64_t renderTimeMs;
int64_t decodeStartTimeMs;
void* userData;
VideoRotation rotation;
VideoContentType content_type;
EncodedImage::Timing timing;
int64_t ntp_time_ms;
absl::optional<ColorSpace> color_space;
};
class VCMDecodedFrameCallback : public DecodedImageCallback {
public:
VCMDecodedFrameCallback(VCMTiming* timing, Clock* clock);
~VCMDecodedFrameCallback() override;
void SetUserReceiveCallback(VCMReceiveCallback* receiveCallback);
VCMReceiveCallback* UserReceiveCallback();
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;
void OnDecoderImplementationName(const char* implementation_name);
void Map(uint32_t timestamp, VCMFrameInformation* frameInfo);
int32_t Pop(uint32_t timestamp);
private:
rtc::ThreadChecker construction_thread_;
// Protect |_timestampMap|.
Clock* const _clock;
// This callback must be set before the decoder thread starts running
// and must only be unset when external threads (e.g decoder thread)
// have been stopped. Due to that, the variable should regarded as const
// while there are more than one threads involved, it must be set
// from the same thread, and therfore a lock is not required to access it.
VCMReceiveCallback* _receiveCallback = nullptr;
VCMTiming* _timing;
rtc::CriticalSection lock_;
VCMTimestampMap _timestampMap RTC_GUARDED_BY(lock_);
int64_t ntp_offset_;
};
class VCMGenericDecoder {
public:
explicit VCMGenericDecoder(std::unique_ptr<VideoDecoder> decoder);
explicit VCMGenericDecoder(VideoDecoder* decoder, bool isExternal = false);
~VCMGenericDecoder();
/**
* Initialize the decoder with the information from the VideoCodec
*/
int32_t InitDecode(const VideoCodec* settings, int32_t numberOfCores);
/**
* Decode to a raw I420 frame,
*
* inputVideoBuffer reference to encoded video frame
*/
int32_t Decode(const VCMEncodedFrame& inputFrame, int64_t nowMs);
/**
* Set decode callback. Deregistering while decoding is illegal.
*/
int32_t RegisterDecodeCompleteCallback(VCMDecodedFrameCallback* callback);
bool PrefersLateDecoding() const;
bool IsSameDecoder(VideoDecoder* decoder) const {
return decoder_.get() == decoder;
}
private:
VCMDecodedFrameCallback* _callback;
VCMFrameInformation _frameInfos[kDecoderFrameMemoryLength];
uint32_t _nextFrameInfoIdx;
std::unique_ptr<VideoDecoder> decoder_;
VideoCodecType _codecType;
const bool _isExternal;
VideoContentType _last_keyframe_content_type;
};
} // namespace webrtc
#endif // MODULES_VIDEO_CODING_GENERIC_DECODER_H_