Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(540)

Unified Diff: webrtc/modules/video_coding/video_receiver.cc

Issue 1853813002: Add support for writing raw encoder output to .ivf files. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Changed out path for test files Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/video_coding/video_receiver.cc
diff --git a/webrtc/modules/video_coding/video_receiver.cc b/webrtc/modules/video_coding/video_receiver.cc
index 136f7d7830816d1737906af590baffb4a0aad1a5..fe392de8fd5ab80e3869187cc11c79e51719f7a7 100644
--- a/webrtc/modules/video_coding/video_receiver.cc
+++ b/webrtc/modules/video_coding/video_receiver.cc
@@ -20,8 +20,6 @@
#include "webrtc/modules/video_coding/video_coding_impl.h"
#include "webrtc/system_wrappers/include/clock.h"
-// #define DEBUG_DECODER_BIT_STREAM
-
namespace webrtc {
namespace vcm {
@@ -30,8 +28,6 @@ VideoReceiver::VideoReceiver(Clock* clock,
NackSender* nack_sender,
KeyFrameRequestSender* keyframe_request_sender)
: clock_(clock),
- process_crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
- _receiveCritSect(CriticalSectionWrapper::CreateCriticalSection()),
_timing(clock_),
_receiver(&_timing,
clock_,
@@ -39,50 +35,38 @@ VideoReceiver::VideoReceiver(Clock* clock,
nack_sender,
keyframe_request_sender),
_decodedFrameCallback(&_timing, clock_),
- _frameTypeCallback(NULL),
- _receiveStatsCallback(NULL),
- _decoderTimingCallback(NULL),
- _packetRequestCallback(NULL),
- render_buffer_callback_(NULL),
- _decoder(NULL),
-#ifdef DEBUG_DECODER_BIT_STREAM
- _bitStreamBeforeDecoder(NULL),
-#endif
+ _frameTypeCallback(nullptr),
+ _receiveStatsCallback(nullptr),
+ _decoderTimingCallback(nullptr),
+ _packetRequestCallback(nullptr),
+ render_buffer_callback_(nullptr),
+ _decoder(nullptr),
_frameFromFile(),
_scheduleKeyRequest(false),
drop_frames_until_keyframe_(false),
max_nack_list_size_(0),
_codecDataBase(nullptr, nullptr),
- pre_decode_image_callback_(NULL),
+ pre_decode_image_callback_(nullptr),
_receiveStatsTimer(1000, clock_),
_retransmissionTimer(10, clock_),
- _keyRequestTimer(500, clock_) {
- assert(clock_);
-#ifdef DEBUG_DECODER_BIT_STREAM
- _bitStreamBeforeDecoder = fopen("decoderBitStream.bit", "wb");
-#endif
-}
+ _keyRequestTimer(500, clock_),
+ ssrc_(0) {}
-VideoReceiver::~VideoReceiver() {
- delete _receiveCritSect;
-#ifdef DEBUG_DECODER_BIT_STREAM
- fclose(_bitStreamBeforeDecoder);
-#endif
-}
+VideoReceiver::~VideoReceiver() {}
void VideoReceiver::Process() {
// Receive-side statistics
if (_receiveStatsTimer.TimeUntilProcess() == 0) {
_receiveStatsTimer.Processed();
- CriticalSectionScoped cs(process_crit_sect_.get());
- if (_receiveStatsCallback != NULL) {
+ rtc::CritScope cs(&process_lock_);
+ if (_receiveStatsCallback != nullptr) {
uint32_t bitRate;
uint32_t frameRate;
_receiver.ReceiveStatistics(&bitRate, &frameRate);
_receiveStatsCallback->OnReceiveRatesUpdated(bitRate, frameRate);
}
- if (_decoderTimingCallback != NULL) {
+ if (_decoderTimingCallback != nullptr) {
int decode_ms;
int max_decode_ms;
int current_delay_ms;
@@ -110,8 +94,8 @@ void VideoReceiver::Process() {
_keyRequestTimer.Processed();
bool request_key_frame = false;
{
- CriticalSectionScoped cs(process_crit_sect_.get());
- request_key_frame = _scheduleKeyRequest && _frameTypeCallback != NULL;
+ rtc::CritScope cs(&process_lock_);
+ request_key_frame = _scheduleKeyRequest && _frameTypeCallback != nullptr;
}
if (request_key_frame)
RequestKeyFrame();
@@ -129,9 +113,9 @@ void VideoReceiver::Process() {
bool callback_registered = false;
uint16_t length;
{
- CriticalSectionScoped cs(process_crit_sect_.get());
+ rtc::CritScope cs(&process_lock_);
length = max_nack_list_size_;
- callback_registered = _packetRequestCallback != NULL;
+ callback_registered = _packetRequestCallback != nullptr;
}
if (callback_registered && length > 0) {
// Collect sequence numbers from the default receiver.
@@ -142,8 +126,8 @@ void VideoReceiver::Process() {
ret = RequestKeyFrame();
}
if (ret == VCM_OK && !nackList.empty()) {
- CriticalSectionScoped cs(process_crit_sect_.get());
- if (_packetRequestCallback != NULL) {
+ rtc::CritScope cs(&process_lock_);
+ if (_packetRequestCallback != nullptr) {
_packetRequestCallback->ResendPackets(&nackList[0], nackList.size());
}
}
@@ -168,7 +152,7 @@ int64_t VideoReceiver::TimeUntilNextProcess() {
}
int32_t VideoReceiver::SetReceiveChannelParameters(int64_t rtt) {
- CriticalSectionScoped receiveCs(_receiveCritSect);
+ rtc::CritScope cs(&receive_lock_);
_receiver.UpdateRtt(rtt);
return 0;
}
@@ -189,7 +173,7 @@ int32_t VideoReceiver::SetVideoProtection(VCMVideoProtection videoProtection,
}
case kProtectionNackFEC: {
- CriticalSectionScoped cs(_receiveCritSect);
+ rtc::CritScope cs(&receive_lock_);
RTC_DCHECK(enable);
_receiver.SetNackMode(kNack, media_optimization::kLowRttNackMs, -1);
_receiver.SetDecodeErrorMode(kNoErrors);
@@ -210,14 +194,14 @@ int32_t VideoReceiver::SetVideoProtection(VCMVideoProtection videoProtection,
// ready for rendering.
int32_t VideoReceiver::RegisterReceiveCallback(
VCMReceiveCallback* receiveCallback) {
- CriticalSectionScoped cs(_receiveCritSect);
+ rtc::CritScope cs(&receive_lock_);
_decodedFrameCallback.SetUserReceiveCallback(receiveCallback);
return VCM_OK;
}
int32_t VideoReceiver::RegisterReceiveStatisticsCallback(
VCMReceiveStatisticsCallback* receiveStats) {
- CriticalSectionScoped cs(process_crit_sect_.get());
+ rtc::CritScope cs(&process_lock_);
_receiver.RegisterStatsCallback(receiveStats);
_receiveStatsCallback = receiveStats;
return VCM_OK;
@@ -225,7 +209,7 @@ int32_t VideoReceiver::RegisterReceiveStatisticsCallback(
int32_t VideoReceiver::RegisterDecoderTimingCallback(
VCMDecoderTimingCallback* decoderTiming) {
- CriticalSectionScoped cs(process_crit_sect_.get());
+ rtc::CritScope cs(&process_lock_);
_decoderTimingCallback = decoderTiming;
return VCM_OK;
}
@@ -233,10 +217,10 @@ int32_t VideoReceiver::RegisterDecoderTimingCallback(
// Register an externally defined decoder object.
void VideoReceiver::RegisterExternalDecoder(VideoDecoder* externalDecoder,
uint8_t payloadType) {
- CriticalSectionScoped cs(_receiveCritSect);
- if (externalDecoder == NULL) {
+ rtc::CritScope cs(&receive_lock_);
+ if (externalDecoder == nullptr) {
// Make sure the VCM updates the decoder next time it decodes.
- _decoder = NULL;
+ _decoder = nullptr;
RTC_CHECK(_codecDataBase.DeregisterExternalDecoder(payloadType));
return;
}
@@ -246,21 +230,21 @@ void VideoReceiver::RegisterExternalDecoder(VideoDecoder* externalDecoder,
// Register a frame type request callback.
int32_t VideoReceiver::RegisterFrameTypeCallback(
VCMFrameTypeCallback* frameTypeCallback) {
- CriticalSectionScoped cs(process_crit_sect_.get());
+ rtc::CritScope cs(&process_lock_);
_frameTypeCallback = frameTypeCallback;
return VCM_OK;
}
int32_t VideoReceiver::RegisterPacketRequestCallback(
VCMPacketRequestCallback* callback) {
- CriticalSectionScoped cs(process_crit_sect_.get());
+ rtc::CritScope cs(&process_lock_);
_packetRequestCallback = callback;
return VCM_OK;
}
int VideoReceiver::RegisterRenderBufferSizeCallback(
VCMRenderBufferSizeCallback* callback) {
- CriticalSectionScoped cs(process_crit_sect_.get());
+ rtc::CritScope cs(&process_lock_);
render_buffer_callback_ = callback;
return VCM_OK;
}
@@ -275,7 +259,7 @@ int32_t VideoReceiver::Decode(uint16_t maxWaitTimeMs) {
int64_t nextRenderTimeMs;
bool prefer_late_decoding = false;
{
- CriticalSectionScoped cs(_receiveCritSect);
+ rtc::CritScope cs(&receive_lock_);
prefer_late_decoding = _codecDataBase.PrefersLateDecoding();
}
@@ -286,7 +270,7 @@ int32_t VideoReceiver::Decode(uint16_t maxWaitTimeMs) {
return VCM_FRAME_NOT_READY;
{
- CriticalSectionScoped cs(process_crit_sect_.get());
+ rtc::CritScope cs(&process_lock_);
if (drop_frames_until_keyframe_) {
// Still getting delta frames, schedule another keyframe request as if
// decode failed.
@@ -298,8 +282,8 @@ int32_t VideoReceiver::Decode(uint16_t maxWaitTimeMs) {
drop_frames_until_keyframe_ = false;
}
}
- CriticalSectionScoped cs(_receiveCritSect);
+ rtc::CritScope cs(&receive_lock_);
// If this frame was too late, we should adjust the delay accordingly
_timing.UpdateCurrentDelay(frame->RenderTimeMs(),
clock_->TimeInMilliseconds());
@@ -311,18 +295,8 @@ int32_t VideoReceiver::Decode(uint16_t maxWaitTimeMs) {
encoded_image.qp_ = qp;
}
pre_decode_image_callback_->Encoded(encoded_image, frame->CodecSpecific(),
pbos-webrtc 2016/04/12 11:20:55 Can you wire up this through here instead? Then yo
sprang_webrtc 2016/04/12 14:06:17 Done.
- NULL);
- }
-
-#ifdef DEBUG_DECODER_BIT_STREAM
- if (_bitStreamBeforeDecoder != NULL) {
- // Write bit stream to file for debugging purposes
- if (fwrite(frame->Buffer(), 1, frame->Length(), _bitStreamBeforeDecoder) !=
- frame->Length()) {
- return -1;
- }
+ nullptr);
}
-#endif
if (first_frame_received_()) {
LOG(LS_INFO) << "Received first "
@@ -338,8 +312,8 @@ int32_t VideoReceiver::Decode(uint16_t maxWaitTimeMs) {
int32_t VideoReceiver::RequestSliceLossIndication(
const uint64_t pictureID) const {
TRACE_EVENT1("webrtc", "RequestSLI", "picture_id", pictureID);
- CriticalSectionScoped cs(process_crit_sect_.get());
- if (_frameTypeCallback != NULL) {
+ rtc::CritScope cs(&process_lock_);
+ if (_frameTypeCallback != nullptr) {
const int32_t ret =
_frameTypeCallback->SliceLossIndicationRequest(pictureID);
if (ret < 0) {
@@ -353,8 +327,8 @@ int32_t VideoReceiver::RequestSliceLossIndication(
int32_t VideoReceiver::RequestKeyFrame() {
TRACE_EVENT0("webrtc", "RequestKeyFrame");
- CriticalSectionScoped process_cs(process_crit_sect_.get());
- if (_frameTypeCallback != NULL) {
+ rtc::CritScope cs(&process_lock_);
+ if (_frameTypeCallback != nullptr) {
const int32_t ret = _frameTypeCallback->RequestKeyFrame();
if (ret < 0) {
return ret;
@@ -368,11 +342,41 @@ int32_t VideoReceiver::RequestKeyFrame() {
// Must be called from inside the receive side critical section.
int32_t VideoReceiver::Decode(const VCMEncodedFrame& frame) {
+ if (kEnableFrameRecording) {
+ rtc::CritScope cs(&file_write_lock_);
+ if (!file_writer_.get()) {
+ RTC_DCHECK(frame.CodecSpecific());
+ RtpVideoCodecTypes rtp_codec_type;
+ switch (frame.CodecSpecific()->codecType) {
+ case kVideoCodecVP8:
+ rtp_codec_type = kRtpVideoVp8;
+ break;
+ case kVideoCodecVP9:
+ rtp_codec_type = kRtpVideoVp9;
+ break;
+ case kVideoCodecH264:
+ rtp_codec_type = kRtpVideoH264;
+ break;
+ default:
+ rtp_codec_type = kRtpVideoNone;
+ RTC_NOTREACHED() << "Unsupported codec "
+ << frame.CodecSpecific()->codecType;
+ }
+ std::ostringstream oss;
+ oss << "receive_bitstream_ssrc_" << ssrc_ << ".ivf";
+ file_writer_ = IvfFileWriter::Open(oss.str(), rtp_codec_type);
+ }
+ if (file_writer_.get()) {
+ bool ok = file_writer_->WriteFrame(frame.EncodedImage());
pbos-webrtc 2016/04/12 11:20:55 This is now done under the receive critsect?
sprang_webrtc 2016/04/12 14:06:17 Yes.
+ RTC_DCHECK(ok);
+ }
+ }
+
TRACE_EVENT_ASYNC_STEP1("webrtc", "Video", frame.TimeStamp(), "Decode",
"type", frame.FrameType());
// Change decoder if payload type has changed
_decoder = _codecDataBase.GetDecoder(frame, &_decodedFrameCallback);
- if (_decoder == NULL) {
+ if (_decoder == nullptr) {
return VCM_NO_CODEC_REGISTERED;
}
// Decode a frame
@@ -396,7 +400,7 @@ int32_t VideoReceiver::Decode(const VCMEncodedFrame& frame) {
ret = VCM_OK;
}
if (request_key_frame) {
- CriticalSectionScoped cs(process_crit_sect_.get());
+ rtc::CritScope cs(&process_lock_);
_scheduleKeyRequest = true;
}
TRACE_EVENT_ASYNC_END0("webrtc", "Video", frame.TimeStamp());
@@ -407,8 +411,8 @@ int32_t VideoReceiver::Decode(const VCMEncodedFrame& frame) {
int32_t VideoReceiver::RegisterReceiveCodec(const VideoCodec* receiveCodec,
int32_t numberOfCores,
bool requireKeyFrame) {
- CriticalSectionScoped cs(_receiveCritSect);
- if (receiveCodec == NULL) {
+ rtc::CritScope cs(&receive_lock_);
+ if (receiveCodec == nullptr) {
return VCM_PARAMETER_ERROR;
}
if (!_codecDataBase.RegisterReceiveCodec(receiveCodec, numberOfCores,
@@ -420,8 +424,8 @@ int32_t VideoReceiver::RegisterReceiveCodec(const VideoCodec* receiveCodec,
// Get current received codec
int32_t VideoReceiver::ReceiveCodec(VideoCodec* currentReceiveCodec) const {
- CriticalSectionScoped cs(_receiveCritSect);
- if (currentReceiveCodec == NULL) {
+ rtc::CritScope cs(&receive_lock_);
+ if (currentReceiveCodec == nullptr) {
return VCM_PARAMETER_ERROR;
}
return _codecDataBase.ReceiveCodec(currentReceiveCodec) ? 0 : -1;
@@ -429,7 +433,7 @@ int32_t VideoReceiver::ReceiveCodec(VideoCodec* currentReceiveCodec) const {
// Get current received codec
VideoCodecType VideoReceiver::ReceiveCodec() const {
- CriticalSectionScoped cs(_receiveCritSect);
+ rtc::CritScope cs(&receive_lock_);
return _codecDataBase.ReceiveCodec();
}
@@ -441,7 +445,7 @@ int32_t VideoReceiver::IncomingPacket(const uint8_t* incomingPayload,
TRACE_EVENT1("webrtc", "VCM::PacketKeyFrame", "seqnum",
rtpInfo.header.sequenceNumber);
}
- if (incomingPayload == NULL) {
+ if (incomingPayload == nullptr) {
// The jitter buffer doesn't handle non-zero payload lengths for packets
// without payload.
// TODO(holmer): We should fix this in the jitter buffer.
@@ -450,11 +454,17 @@ int32_t VideoReceiver::IncomingPacket(const uint8_t* incomingPayload,
const VCMPacket packet(incomingPayload, payloadLength, rtpInfo);
int32_t ret = _receiver.InsertPacket(packet, rtpInfo.type.Video.width,
rtpInfo.type.Video.height);
+
+ if (kEnableFrameRecording) {
+ rtc::CritScope cs(&file_write_lock_);
+ ssrc_ = rtpInfo.header.ssrc;
+ }
+
// TODO(holmer): Investigate if this somehow should use the key frame
// request scheduling to throttle the requests.
if (ret == VCM_FLUSH_INDICATOR) {
{
- CriticalSectionScoped process_cs(process_crit_sect_.get());
+ rtc::CritScope cs(&process_lock_);
drop_frames_until_keyframe_ = true;
}
RequestKeyFrame();
@@ -491,7 +501,7 @@ uint32_t VideoReceiver::DiscardedPackets() const {
int VideoReceiver::SetReceiverRobustnessMode(
ReceiverRobustness robustnessMode,
VCMDecodeErrorMode decode_error_mode) {
- CriticalSectionScoped cs(_receiveCritSect);
+ rtc::CritScope cs(&receive_lock_);
switch (robustnessMode) {
case VideoCodingModule::kNone:
_receiver.SetNackMode(kNoNack, -1, -1);
@@ -527,7 +537,7 @@ int VideoReceiver::SetReceiverRobustnessMode(
}
void VideoReceiver::SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode) {
- CriticalSectionScoped cs(_receiveCritSect);
+ rtc::CritScope cs(&receive_lock_);
_receiver.SetDecodeErrorMode(decode_error_mode);
}
@@ -535,7 +545,7 @@ void VideoReceiver::SetNackSettings(size_t max_nack_list_size,
int max_packet_age_to_nack,
int max_incomplete_time_ms) {
if (max_nack_list_size != 0) {
- CriticalSectionScoped process_cs(process_crit_sect_.get());
+ rtc::CritScope cs(&process_lock_);
max_nack_list_size_ = max_nack_list_size;
}
_receiver.SetNackSettings(max_nack_list_size, max_packet_age_to_nack,
@@ -548,7 +558,7 @@ int VideoReceiver::SetMinReceiverDelay(int desired_delay_ms) {
void VideoReceiver::RegisterPreDecodeImageCallback(
EncodedImageCallback* observer) {
- CriticalSectionScoped cs(_receiveCritSect);
+ rtc::CritScope cs(&receive_lock_);
pre_decode_image_callback_ = observer;
pbos-webrtc 2016/04/12 11:22:33 Actually, can we require this to be set before rec
sprang_webrtc 2016/04/12 14:06:17 Done.
}

Powered by Google App Engine
This is Rietveld 408576698