2011-07-07 08:21:25 +00:00
|
|
|
/*
|
2012-02-13 09:03:53 +00:00
|
|
|
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
2011-07-07 08:21:25 +00:00
|
|
|
*
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
|
|
|
|
|
2015-04-08 13:00:10 -07:00
|
|
|
#include "webrtc/base/checks.h"
|
2015-11-16 16:39:06 -08:00
|
|
|
#include "webrtc/base/logging.h"
|
2015-11-17 06:03:43 -08:00
|
|
|
#include "webrtc/base/trace_event.h"
|
2013-07-16 12:32:05 +00:00
|
|
|
#include "webrtc/engine_configurations.h"
|
|
|
|
|
#include "webrtc/modules/video_coding/main/source/encoded_frame.h"
|
|
|
|
|
#include "webrtc/modules/video_coding/main/source/generic_encoder.h"
|
|
|
|
|
#include "webrtc/modules/video_coding/main/source/media_optimization.h"
|
2015-10-28 18:17:40 +01:00
|
|
|
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
|
2011-07-07 08:21:25 +00:00
|
|
|
|
|
|
|
|
namespace webrtc {
|
2014-01-09 08:04:32 +00:00
|
|
|
namespace {
|
|
|
|
|
// Map information from info into rtp. If no relevant information is found
|
|
|
|
|
// in info, rtp is set to NULL.
|
2015-04-08 13:00:10 -07:00
|
|
|
void CopyCodecSpecific(const CodecSpecificInfo* info, RTPVideoHeader* rtp) {
|
2015-09-17 00:24:34 -07:00
|
|
|
RTC_DCHECK(info);
|
2014-01-09 08:04:32 +00:00
|
|
|
switch (info->codecType) {
|
|
|
|
|
case kVideoCodecVP8: {
|
2015-04-08 13:00:10 -07:00
|
|
|
rtp->codec = kRtpVideoVp8;
|
|
|
|
|
rtp->codecHeader.VP8.InitRTPVideoHeaderVP8();
|
|
|
|
|
rtp->codecHeader.VP8.pictureId = info->codecSpecific.VP8.pictureId;
|
|
|
|
|
rtp->codecHeader.VP8.nonReference =
|
2014-01-09 08:04:32 +00:00
|
|
|
info->codecSpecific.VP8.nonReference;
|
2015-04-08 13:00:10 -07:00
|
|
|
rtp->codecHeader.VP8.temporalIdx = info->codecSpecific.VP8.temporalIdx;
|
|
|
|
|
rtp->codecHeader.VP8.layerSync = info->codecSpecific.VP8.layerSync;
|
|
|
|
|
rtp->codecHeader.VP8.tl0PicIdx = info->codecSpecific.VP8.tl0PicIdx;
|
|
|
|
|
rtp->codecHeader.VP8.keyIdx = info->codecSpecific.VP8.keyIdx;
|
|
|
|
|
rtp->simulcastIdx = info->codecSpecific.VP8.simulcastIdx;
|
2014-01-09 08:04:32 +00:00
|
|
|
return;
|
2015-07-31 06:10:09 -07:00
|
|
|
}
|
|
|
|
|
case kVideoCodecVP9: {
|
|
|
|
|
rtp->codec = kRtpVideoVp9;
|
|
|
|
|
rtp->codecHeader.VP9.InitRTPVideoHeaderVP9();
|
|
|
|
|
rtp->codecHeader.VP9.inter_pic_predicted =
|
|
|
|
|
info->codecSpecific.VP9.inter_pic_predicted;
|
|
|
|
|
rtp->codecHeader.VP9.flexible_mode =
|
|
|
|
|
info->codecSpecific.VP9.flexible_mode;
|
|
|
|
|
rtp->codecHeader.VP9.ss_data_available =
|
|
|
|
|
info->codecSpecific.VP9.ss_data_available;
|
|
|
|
|
rtp->codecHeader.VP9.picture_id = info->codecSpecific.VP9.picture_id;
|
|
|
|
|
rtp->codecHeader.VP9.tl0_pic_idx = info->codecSpecific.VP9.tl0_pic_idx;
|
|
|
|
|
rtp->codecHeader.VP9.temporal_idx = info->codecSpecific.VP9.temporal_idx;
|
|
|
|
|
rtp->codecHeader.VP9.spatial_idx = info->codecSpecific.VP9.spatial_idx;
|
|
|
|
|
rtp->codecHeader.VP9.temporal_up_switch =
|
|
|
|
|
info->codecSpecific.VP9.temporal_up_switch;
|
|
|
|
|
rtp->codecHeader.VP9.inter_layer_predicted =
|
|
|
|
|
info->codecSpecific.VP9.inter_layer_predicted;
|
|
|
|
|
rtp->codecHeader.VP9.gof_idx = info->codecSpecific.VP9.gof_idx;
|
2015-09-08 02:40:29 -07:00
|
|
|
rtp->codecHeader.VP9.num_spatial_layers =
|
|
|
|
|
info->codecSpecific.VP9.num_spatial_layers;
|
Reland of Work on flexible mode and screen sharing. (patchset #1 id:1 of https://codereview.webrtc.org/1438543002/ )
Reason for revert:
Failed test not related to this CL (test fails on
master at an earlier date), re-landing original CL..
(This time from my @webrtc account.)
Original issue's description:
> Revert of Work on flexible mode and screen sharing. (patchset #28 id:520001 of https://codereview.webrtc.org/1328113004/ )
>
> Reason for revert:
> Seems to break VideoSendStreamTest.ReconfigureBitratesSetsEncoderBitratesCorrectly on Linux Memcheck buildbot.
>
> Original issue's description:
> > Work on flexible mode and screen sharing.
> >
> > Implement VP8 style screensharing but with spatial layers.
> > Implement flexible mode.
> >
> > Files from other patches:
> > generic_encoder.cc
> > layer_filtering_transport.cc
> >
> > BUG=webrtc:4914
> >
> > Committed: https://crrev.com/77ccfb4d16c148e61a316746bb5d9705e8b39f4a
> > Cr-Commit-Position: refs/heads/master@{#10572}
>
> TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,philipel@webrtc.org
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:4914
>
> Committed: https://crrev.com/0be8f1d347bdb171462df89c2a4c69b3f3eb7519
> Cr-Commit-Position: refs/heads/master@{#10578}
TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,terelius@webrtc.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:4914
Review URL: https://codereview.webrtc.org/1431283002
Cr-Commit-Position: refs/heads/master@{#10581}
2015-11-10 07:17:23 -08:00
|
|
|
|
2015-07-31 06:10:09 -07:00
|
|
|
if (info->codecSpecific.VP9.ss_data_available) {
|
|
|
|
|
rtp->codecHeader.VP9.spatial_layer_resolution_present =
|
|
|
|
|
info->codecSpecific.VP9.spatial_layer_resolution_present;
|
|
|
|
|
if (info->codecSpecific.VP9.spatial_layer_resolution_present) {
|
|
|
|
|
for (size_t i = 0; i < info->codecSpecific.VP9.num_spatial_layers;
|
|
|
|
|
++i) {
|
|
|
|
|
rtp->codecHeader.VP9.width[i] = info->codecSpecific.VP9.width[i];
|
|
|
|
|
rtp->codecHeader.VP9.height[i] = info->codecSpecific.VP9.height[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
rtp->codecHeader.VP9.gof.CopyGofInfoVP9(info->codecSpecific.VP9.gof);
|
|
|
|
|
}
|
Reland of Work on flexible mode and screen sharing. (patchset #1 id:1 of https://codereview.webrtc.org/1438543002/ )
Reason for revert:
Failed test not related to this CL (test fails on
master at an earlier date), re-landing original CL..
(This time from my @webrtc account.)
Original issue's description:
> Revert of Work on flexible mode and screen sharing. (patchset #28 id:520001 of https://codereview.webrtc.org/1328113004/ )
>
> Reason for revert:
> Seems to break VideoSendStreamTest.ReconfigureBitratesSetsEncoderBitratesCorrectly on Linux Memcheck buildbot.
>
> Original issue's description:
> > Work on flexible mode and screen sharing.
> >
> > Implement VP8 style screensharing but with spatial layers.
> > Implement flexible mode.
> >
> > Files from other patches:
> > generic_encoder.cc
> > layer_filtering_transport.cc
> >
> > BUG=webrtc:4914
> >
> > Committed: https://crrev.com/77ccfb4d16c148e61a316746bb5d9705e8b39f4a
> > Cr-Commit-Position: refs/heads/master@{#10572}
>
> TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,philipel@webrtc.org
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:4914
>
> Committed: https://crrev.com/0be8f1d347bdb171462df89c2a4c69b3f3eb7519
> Cr-Commit-Position: refs/heads/master@{#10578}
TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,terelius@webrtc.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:4914
Review URL: https://codereview.webrtc.org/1431283002
Cr-Commit-Position: refs/heads/master@{#10581}
2015-11-10 07:17:23 -08:00
|
|
|
|
|
|
|
|
rtp->codecHeader.VP9.num_ref_pics = info->codecSpecific.VP9.num_ref_pics;
|
|
|
|
|
for (int i = 0; i < info->codecSpecific.VP9.num_ref_pics; ++i)
|
|
|
|
|
rtp->codecHeader.VP9.pid_diff[i] = info->codecSpecific.VP9.p_diff[i];
|
2015-07-31 06:10:09 -07:00
|
|
|
return;
|
2014-01-09 08:04:32 +00:00
|
|
|
}
|
2014-07-31 14:59:24 +00:00
|
|
|
case kVideoCodecH264:
|
2015-04-08 13:00:10 -07:00
|
|
|
rtp->codec = kRtpVideoH264;
|
2014-07-31 14:59:24 +00:00
|
|
|
return;
|
2014-01-09 08:04:32 +00:00
|
|
|
case kVideoCodecGeneric:
|
2015-04-08 13:00:10 -07:00
|
|
|
rtp->codec = kRtpVideoGeneric;
|
|
|
|
|
rtp->simulcastIdx = info->codecSpecific.generic.simulcast_idx;
|
2014-01-09 08:04:32 +00:00
|
|
|
return;
|
|
|
|
|
default:
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} // namespace
|
2011-07-07 08:21:25 +00:00
|
|
|
|
|
|
|
|
//#define DEBUG_ENCODER_BIT_STREAM
|
|
|
|
|
|
2015-10-29 16:53:59 +01:00
|
|
|
VCMGenericEncoder::VCMGenericEncoder(
|
|
|
|
|
VideoEncoder* encoder,
|
|
|
|
|
VideoEncoderRateObserver* rate_observer,
|
|
|
|
|
VCMEncodedFrameCallback* encoded_frame_callback,
|
|
|
|
|
bool internalSource)
|
2015-02-26 13:15:22 +00:00
|
|
|
: encoder_(encoder),
|
|
|
|
|
rate_observer_(rate_observer),
|
2015-10-29 16:53:59 +01:00
|
|
|
vcm_encoded_frame_callback_(encoded_frame_callback),
|
2015-03-17 21:54:50 +00:00
|
|
|
internal_source_(internalSource),
|
2015-10-29 16:53:59 +01:00
|
|
|
encoder_params_({0, 0, 0, 0}),
|
2015-06-24 11:24:44 +02:00
|
|
|
rotation_(kVideoRotation_0),
|
2015-10-29 16:30:23 +01:00
|
|
|
is_screenshare_(false) {}
|
2011-07-07 08:21:25 +00:00
|
|
|
|
2015-10-29 16:53:59 +01:00
|
|
|
VCMGenericEncoder::~VCMGenericEncoder() {}
|
2015-03-07 20:55:56 +00:00
|
|
|
|
2015-10-29 16:53:59 +01:00
|
|
|
int32_t VCMGenericEncoder::Release() {
|
|
|
|
|
return encoder_->Release();
|
2011-07-07 08:21:25 +00:00
|
|
|
}
|
|
|
|
|
|
2015-10-29 16:53:59 +01:00
|
|
|
int32_t VCMGenericEncoder::InitEncode(const VideoCodec* settings,
|
|
|
|
|
int32_t numberOfCores,
|
|
|
|
|
size_t maxPayloadSize) {
|
2015-11-17 06:03:43 -08:00
|
|
|
TRACE_EVENT0("webrtc", "VCMGenericEncoder::InitEncode");
|
2015-10-29 16:53:59 +01:00
|
|
|
{
|
|
|
|
|
rtc::CritScope lock(¶ms_lock_);
|
|
|
|
|
encoder_params_.target_bitrate = settings->startBitrate * 1000;
|
|
|
|
|
encoder_params_.input_frame_rate = settings->maxFramerate;
|
|
|
|
|
}
|
2015-03-07 20:55:56 +00:00
|
|
|
|
2015-10-29 16:53:59 +01:00
|
|
|
is_screenshare_ = settings->mode == VideoCodecMode::kScreensharing;
|
|
|
|
|
if (encoder_->InitEncode(settings, numberOfCores, maxPayloadSize) != 0) {
|
|
|
|
|
LOG(LS_ERROR) << "Failed to initialize the encoder associated with "
|
|
|
|
|
"payload name: "
|
|
|
|
|
<< settings->plName;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
encoder_->RegisterEncodeCompleteCallback(vcm_encoded_frame_callback_);
|
|
|
|
|
return 0;
|
2011-07-07 08:21:25 +00:00
|
|
|
}
|
|
|
|
|
|
2015-05-29 17:21:40 -07:00
|
|
|
int32_t VCMGenericEncoder::Encode(const VideoFrame& inputFrame,
|
|
|
|
|
const CodecSpecificInfo* codecSpecificInfo,
|
|
|
|
|
const std::vector<FrameType>& frameTypes) {
|
2015-11-17 06:03:43 -08:00
|
|
|
TRACE_EVENT1("webrtc", "VCMGenericEncoder::Encode", "timestamp",
|
|
|
|
|
inputFrame.timestamp());
|
|
|
|
|
|
2015-10-19 02:39:06 -07:00
|
|
|
for (FrameType frame_type : frameTypes)
|
|
|
|
|
RTC_DCHECK(frame_type == kVideoFrameKey || frame_type == kVideoFrameDelta);
|
2015-03-17 21:54:50 +00:00
|
|
|
|
|
|
|
|
rotation_ = inputFrame.rotation();
|
|
|
|
|
|
2015-10-29 16:53:59 +01:00
|
|
|
// Keep track of the current frame rotation and apply to the output of the
|
|
|
|
|
// encoder. There might not be exact as the encoder could have one frame delay
|
|
|
|
|
// but it should be close enough.
|
|
|
|
|
// TODO(pbos): Map from timestamp, this is racy (even if rotation_ is locked
|
|
|
|
|
// properly, which it isn't). More than one frame may be in the pipeline.
|
|
|
|
|
vcm_encoded_frame_callback_->SetRotation(rotation_);
|
2015-03-17 21:54:50 +00:00
|
|
|
|
2015-10-19 02:39:06 -07:00
|
|
|
int32_t result = encoder_->Encode(inputFrame, codecSpecificInfo, &frameTypes);
|
2015-06-24 11:24:44 +02:00
|
|
|
if (is_screenshare_ &&
|
|
|
|
|
result == WEBRTC_VIDEO_CODEC_TARGET_BITRATE_OVERSHOOT) {
|
|
|
|
|
// Target bitrate exceeded, encoder state has been reset - try again.
|
2015-10-19 02:39:06 -07:00
|
|
|
return encoder_->Encode(inputFrame, codecSpecificInfo, &frameTypes);
|
2015-06-24 11:24:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
2011-07-07 08:21:25 +00:00
|
|
|
}
|
|
|
|
|
|
2015-10-29 16:30:23 +01:00
|
|
|
void VCMGenericEncoder::SetEncoderParameters(const EncoderParameters& params) {
|
|
|
|
|
bool channel_parameters_have_changed;
|
|
|
|
|
bool rates_have_changed;
|
|
|
|
|
{
|
|
|
|
|
rtc::CritScope lock(¶ms_lock_);
|
|
|
|
|
channel_parameters_have_changed =
|
|
|
|
|
params.loss_rate != encoder_params_.loss_rate ||
|
|
|
|
|
params.rtt != encoder_params_.rtt;
|
|
|
|
|
rates_have_changed =
|
|
|
|
|
params.target_bitrate != encoder_params_.target_bitrate ||
|
|
|
|
|
params.input_frame_rate != encoder_params_.input_frame_rate;
|
|
|
|
|
encoder_params_ = params;
|
|
|
|
|
}
|
|
|
|
|
if (channel_parameters_have_changed)
|
|
|
|
|
encoder_->SetChannelParameters(params.loss_rate, params.rtt);
|
|
|
|
|
if (rates_have_changed) {
|
|
|
|
|
uint32_t target_bitrate_kbps = (params.target_bitrate + 500) / 1000;
|
|
|
|
|
encoder_->SetRates(target_bitrate_kbps, params.input_frame_rate);
|
|
|
|
|
if (rate_observer_ != nullptr) {
|
|
|
|
|
rate_observer_->OnSetRates(params.target_bitrate,
|
|
|
|
|
params.input_frame_rate);
|
2011-07-07 08:21:25 +00:00
|
|
|
}
|
2015-10-29 16:30:23 +01:00
|
|
|
}
|
2011-07-07 08:21:25 +00:00
|
|
|
}
|
|
|
|
|
|
2015-10-29 16:30:23 +01:00
|
|
|
EncoderParameters VCMGenericEncoder::GetEncoderParameters() const {
|
|
|
|
|
rtc::CritScope lock(¶ms_lock_);
|
|
|
|
|
return encoder_params_;
|
2011-07-07 08:21:25 +00:00
|
|
|
}
|
|
|
|
|
|
2013-04-02 15:54:38 +00:00
|
|
|
int32_t
|
2011-07-07 08:21:25 +00:00
|
|
|
VCMGenericEncoder::SetPeriodicKeyFrames(bool enable)
|
|
|
|
|
{
|
2015-02-26 13:15:22 +00:00
|
|
|
return encoder_->SetPeriodicKeyFrames(enable);
|
2011-07-07 08:21:25 +00:00
|
|
|
}
|
|
|
|
|
|
2013-04-02 15:54:38 +00:00
|
|
|
int32_t VCMGenericEncoder::RequestFrame(
|
2012-10-25 11:29:51 +00:00
|
|
|
const std::vector<FrameType>& frame_types) {
|
2015-05-29 17:21:40 -07:00
|
|
|
VideoFrame image;
|
2015-10-19 02:39:06 -07:00
|
|
|
return encoder_->Encode(image, NULL, &frame_types);
|
2011-07-07 08:21:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
VCMGenericEncoder::InternalSource() const
|
|
|
|
|
{
|
2015-03-07 20:55:56 +00:00
|
|
|
return internal_source_;
|
2011-07-07 08:21:25 +00:00
|
|
|
}
|
|
|
|
|
|
2015-04-21 15:30:11 -07:00
|
|
|
void VCMGenericEncoder::OnDroppedFrame() {
|
|
|
|
|
encoder_->OnDroppedFrame();
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-05 11:08:03 +02:00
|
|
|
bool VCMGenericEncoder::SupportsNativeHandle() const {
|
|
|
|
|
return encoder_->SupportsNativeHandle();
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-13 16:26:33 -07:00
|
|
|
int VCMGenericEncoder::GetTargetFramerate() {
|
|
|
|
|
return encoder_->GetTargetFramerate();
|
|
|
|
|
}
|
|
|
|
|
|
2011-07-07 08:21:25 +00:00
|
|
|
/***************************
|
|
|
|
|
* Callback Implementation
|
|
|
|
|
***************************/
|
2014-01-09 08:01:57 +00:00
|
|
|
VCMEncodedFrameCallback::VCMEncodedFrameCallback(
|
2015-03-17 21:54:50 +00:00
|
|
|
EncodedImageCallback* post_encode_callback)
|
|
|
|
|
: _sendCallback(),
|
|
|
|
|
_mediaOpt(NULL),
|
|
|
|
|
_payloadType(0),
|
|
|
|
|
_internalSource(false),
|
|
|
|
|
_rotation(kVideoRotation_0),
|
|
|
|
|
post_encode_callback_(post_encode_callback)
|
2012-07-20 11:17:23 +00:00
|
|
|
#ifdef DEBUG_ENCODER_BIT_STREAM
|
2015-03-17 21:54:50 +00:00
|
|
|
,
|
|
|
|
|
_bitStreamAfterEncoder(NULL)
|
2012-07-20 11:17:23 +00:00
|
|
|
#endif
|
2011-07-07 08:21:25 +00:00
|
|
|
{
|
|
|
|
|
#ifdef DEBUG_ENCODER_BIT_STREAM
|
|
|
|
|
_bitStreamAfterEncoder = fopen("encoderBitStream.bit", "wb");
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VCMEncodedFrameCallback::~VCMEncodedFrameCallback()
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG_ENCODER_BIT_STREAM
|
|
|
|
|
fclose(_bitStreamAfterEncoder);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-02 15:54:38 +00:00
|
|
|
int32_t
|
2011-07-07 08:21:25 +00:00
|
|
|
VCMEncodedFrameCallback::SetTransportCallback(VCMPacketizationCallback* transport)
|
|
|
|
|
{
|
|
|
|
|
_sendCallback = transport;
|
|
|
|
|
return VCM_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-09 09:14:03 +00:00
|
|
|
int32_t VCMEncodedFrameCallback::Encoded(
|
|
|
|
|
const EncodedImage& encodedImage,
|
2011-07-07 08:21:25 +00:00
|
|
|
const CodecSpecificInfo* codecSpecificInfo,
|
2015-02-09 09:14:03 +00:00
|
|
|
const RTPFragmentationHeader* fragmentationHeader) {
|
2015-11-17 06:03:43 -08:00
|
|
|
TRACE_EVENT_INSTANT1("webrtc", "VCMEncodedFrameCallback::Encoded",
|
|
|
|
|
"timestamp", encodedImage._timeStamp);
|
2015-10-19 02:39:06 -07:00
|
|
|
RTC_DCHECK(encodedImage._frameType == kVideoFrameKey ||
|
|
|
|
|
encodedImage._frameType == kVideoFrameDelta);
|
2015-02-09 09:14:03 +00:00
|
|
|
post_encode_callback_->Encoded(encodedImage, NULL, NULL);
|
|
|
|
|
|
|
|
|
|
if (_sendCallback == NULL) {
|
|
|
|
|
return VCM_UNINITIALIZED;
|
|
|
|
|
}
|
2014-01-09 08:01:57 +00:00
|
|
|
|
2011-10-25 00:40:43 +00:00
|
|
|
#ifdef DEBUG_ENCODER_BIT_STREAM
|
2015-02-09 09:14:03 +00:00
|
|
|
if (_bitStreamAfterEncoder != NULL) {
|
|
|
|
|
fwrite(encodedImage._buffer, 1, encodedImage._length,
|
|
|
|
|
_bitStreamAfterEncoder);
|
|
|
|
|
}
|
2011-10-25 00:40:43 +00:00
|
|
|
#endif
|
2011-07-07 08:21:25 +00:00
|
|
|
|
2015-02-09 09:14:03 +00:00
|
|
|
RTPVideoHeader rtpVideoHeader;
|
2015-02-18 20:30:03 +00:00
|
|
|
memset(&rtpVideoHeader, 0, sizeof(RTPVideoHeader));
|
2015-02-09 09:14:03 +00:00
|
|
|
RTPVideoHeader* rtpVideoHeaderPtr = &rtpVideoHeader;
|
2015-04-08 13:00:10 -07:00
|
|
|
if (codecSpecificInfo) {
|
|
|
|
|
CopyCodecSpecific(codecSpecificInfo, rtpVideoHeaderPtr);
|
|
|
|
|
}
|
2015-03-17 21:54:50 +00:00
|
|
|
rtpVideoHeader.rotation = _rotation;
|
2011-07-07 08:21:25 +00:00
|
|
|
|
2015-02-09 09:14:03 +00:00
|
|
|
int32_t callbackReturn = _sendCallback->SendData(
|
|
|
|
|
_payloadType, encodedImage, *fragmentationHeader, rtpVideoHeaderPtr);
|
|
|
|
|
if (callbackReturn < 0) {
|
|
|
|
|
return callbackReturn;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_mediaOpt != NULL) {
|
|
|
|
|
_mediaOpt->UpdateWithEncodedData(encodedImage);
|
|
|
|
|
if (_internalSource)
|
|
|
|
|
return _mediaOpt->DropFrame(); // Signal to encoder to drop next frame.
|
|
|
|
|
}
|
|
|
|
|
return VCM_OK;
|
2011-07-07 08:21:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2013-03-04 15:24:40 +00:00
|
|
|
VCMEncodedFrameCallback::SetMediaOpt(
|
2013-09-23 19:54:25 +00:00
|
|
|
media_optimization::MediaOptimization *mediaOpt)
|
2011-07-07 08:21:25 +00:00
|
|
|
{
|
|
|
|
|
_mediaOpt = mediaOpt;
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-03 15:12:26 +00:00
|
|
|
} // namespace webrtc
|