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.
|
|
|
|
|
*/
|
|
|
|
|
|
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"
|
2013-11-26 11:41:59 +00:00
|
|
|
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
2014-04-11 14:08:35 +00:00
|
|
|
#include "webrtc/system_wrappers/interface/logging.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.
|
|
|
|
|
void CopyCodecSpecific(const CodecSpecificInfo* info, RTPVideoHeader** rtp) {
|
|
|
|
|
if (!info) {
|
|
|
|
|
*rtp = NULL;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
switch (info->codecType) {
|
|
|
|
|
case kVideoCodecVP8: {
|
|
|
|
|
(*rtp)->codec = kRtpVideoVp8;
|
|
|
|
|
(*rtp)->codecHeader.VP8.InitRTPVideoHeaderVP8();
|
|
|
|
|
(*rtp)->codecHeader.VP8.pictureId = info->codecSpecific.VP8.pictureId;
|
|
|
|
|
(*rtp)->codecHeader.VP8.nonReference =
|
|
|
|
|
info->codecSpecific.VP8.nonReference;
|
|
|
|
|
(*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;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2014-07-31 14:59:24 +00:00
|
|
|
case kVideoCodecH264:
|
|
|
|
|
(*rtp)->codec = kRtpVideoH264;
|
|
|
|
|
return;
|
2014-01-09 08:04:32 +00:00
|
|
|
case kVideoCodecGeneric:
|
|
|
|
|
(*rtp)->codec = kRtpVideoGeneric;
|
|
|
|
|
(*rtp)->simulcastIdx = info->codecSpecific.generic.simulcast_idx;
|
|
|
|
|
return;
|
|
|
|
|
default:
|
|
|
|
|
// No codec specific info. Change RTP header pointer to NULL.
|
|
|
|
|
*rtp = NULL;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} // namespace
|
2011-07-07 08:21:25 +00:00
|
|
|
|
|
|
|
|
//#define DEBUG_ENCODER_BIT_STREAM
|
|
|
|
|
|
|
|
|
|
VCMGenericEncoder::VCMGenericEncoder(VideoEncoder& encoder, bool internalSource /*= false*/)
|
|
|
|
|
:
|
|
|
|
|
_encoder(encoder),
|
|
|
|
|
_codecType(kVideoCodecUnknown),
|
|
|
|
|
_VCMencodedFrameCallback(NULL),
|
|
|
|
|
_bitRate(0),
|
|
|
|
|
_frameRate(0),
|
2012-10-25 11:29:51 +00:00
|
|
|
_internalSource(internalSource)
|
2011-07-07 08:21:25 +00:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VCMGenericEncoder::~VCMGenericEncoder()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-02 15:54:38 +00:00
|
|
|
int32_t VCMGenericEncoder::Release()
|
2011-07-07 08:21:25 +00:00
|
|
|
{
|
|
|
|
|
_bitRate = 0;
|
|
|
|
|
_frameRate = 0;
|
|
|
|
|
_VCMencodedFrameCallback = NULL;
|
|
|
|
|
return _encoder.Release();
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-02 15:54:38 +00:00
|
|
|
int32_t
|
2011-10-13 15:19:55 +00:00
|
|
|
VCMGenericEncoder::InitEncode(const VideoCodec* settings,
|
2013-04-02 15:54:38 +00:00
|
|
|
int32_t numberOfCores,
|
Use size_t more consistently for packet/payload lengths.
See design doc at https://docs.google.com/a/chromium.org/document/d/1I6nmE9D_BmCY-IoV6MDPY2V6WYpEI-dg2apWXTfZyUI/edit?usp=sharing for more information.
This CL was reviewed and approved in pieces in the following CLs:
https://webrtc-codereview.appspot.com/24209004/
https://webrtc-codereview.appspot.com/24229004/
https://webrtc-codereview.appspot.com/24259004/
https://webrtc-codereview.appspot.com/25109004/
https://webrtc-codereview.appspot.com/26099004/
https://webrtc-codereview.appspot.com/27069004/
https://webrtc-codereview.appspot.com/27969004/
https://webrtc-codereview.appspot.com/27989004/
https://webrtc-codereview.appspot.com/29009004/
https://webrtc-codereview.appspot.com/30929004/
https://webrtc-codereview.appspot.com/30939004/
https://webrtc-codereview.appspot.com/31999004/
Committing as TBR to the original reviewers.
BUG=chromium:81439
TEST=none
TBR=pthatcher,henrik.lundin,tina.legrand,stefan,tkchin,glaznev,kjellander,perkj,mflodman,henrika,asapersson,niklas.enbom
Review URL: https://webrtc-codereview.appspot.com/23129004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@7726 4adac7df-926f-26a2-2b94-8c16560cd09d
2014-11-20 22:28:14 +00:00
|
|
|
size_t maxPayloadSize)
|
2011-07-07 08:21:25 +00:00
|
|
|
{
|
2013-04-11 17:21:40 +00:00
|
|
|
_bitRate = settings->startBitrate * 1000;
|
2011-07-07 08:21:25 +00:00
|
|
|
_frameRate = settings->maxFramerate;
|
|
|
|
|
_codecType = settings->codecType;
|
2014-04-11 14:08:35 +00:00
|
|
|
if (_encoder.InitEncode(settings, numberOfCores, maxPayloadSize) != 0) {
|
|
|
|
|
LOG(LS_ERROR) << "Failed to initialize the encoder associated with "
|
|
|
|
|
"payload name: " << settings->plName;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
2011-07-07 08:21:25 +00:00
|
|
|
}
|
|
|
|
|
|
2013-04-02 15:54:38 +00:00
|
|
|
int32_t
|
2012-10-24 18:33:04 +00:00
|
|
|
VCMGenericEncoder::Encode(const I420VideoFrame& inputFrame,
|
2011-07-07 08:21:25 +00:00
|
|
|
const CodecSpecificInfo* codecSpecificInfo,
|
2012-10-25 11:29:51 +00:00
|
|
|
const std::vector<FrameType>& frameTypes) {
|
|
|
|
|
std::vector<VideoFrameType> video_frame_types(frameTypes.size(),
|
2012-10-08 07:06:53 +00:00
|
|
|
kDeltaFrame);
|
2012-10-25 11:29:51 +00:00
|
|
|
VCMEncodedFrame::ConvertFrameTypes(frameTypes, &video_frame_types);
|
2012-10-08 07:06:53 +00:00
|
|
|
return _encoder.Encode(inputFrame, codecSpecificInfo, &video_frame_types);
|
2011-07-07 08:21:25 +00:00
|
|
|
}
|
|
|
|
|
|
2013-04-02 15:54:38 +00:00
|
|
|
int32_t
|
2015-01-12 21:51:21 +00:00
|
|
|
VCMGenericEncoder::SetChannelParameters(int32_t packetLoss, int64_t rtt)
|
2011-07-07 08:21:25 +00:00
|
|
|
{
|
2011-12-02 08:34:05 +00:00
|
|
|
return _encoder.SetChannelParameters(packetLoss, rtt);
|
2011-07-07 08:21:25 +00:00
|
|
|
}
|
|
|
|
|
|
2013-04-02 15:54:38 +00:00
|
|
|
int32_t
|
|
|
|
|
VCMGenericEncoder::SetRates(uint32_t newBitRate, uint32_t frameRate)
|
2011-07-07 08:21:25 +00:00
|
|
|
{
|
2013-03-19 10:04:57 +00:00
|
|
|
uint32_t target_bitrate_kbps = (newBitRate + 500) / 1000;
|
2013-04-02 15:54:38 +00:00
|
|
|
int32_t ret = _encoder.SetRates(target_bitrate_kbps, frameRate);
|
2011-07-07 08:21:25 +00:00
|
|
|
if (ret < 0)
|
|
|
|
|
{
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
_bitRate = newBitRate;
|
|
|
|
|
_frameRate = frameRate;
|
|
|
|
|
return VCM_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-02 15:54:38 +00:00
|
|
|
int32_t
|
|
|
|
|
VCMGenericEncoder::CodecConfigParameters(uint8_t* buffer, int32_t size)
|
2011-07-07 08:21:25 +00:00
|
|
|
{
|
2013-04-02 15:54:38 +00:00
|
|
|
int32_t ret = _encoder.CodecConfigParameters(buffer, size);
|
2011-07-07 08:21:25 +00:00
|
|
|
if (ret < 0)
|
|
|
|
|
{
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-02 15:54:38 +00:00
|
|
|
uint32_t VCMGenericEncoder::BitRate() const
|
2011-07-07 08:21:25 +00:00
|
|
|
{
|
|
|
|
|
return _bitRate;
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-02 15:54:38 +00:00
|
|
|
uint32_t VCMGenericEncoder::FrameRate() const
|
2011-07-07 08:21:25 +00:00
|
|
|
{
|
|
|
|
|
return _frameRate;
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-02 15:54:38 +00:00
|
|
|
int32_t
|
2011-07-07 08:21:25 +00:00
|
|
|
VCMGenericEncoder::SetPeriodicKeyFrames(bool enable)
|
|
|
|
|
{
|
|
|
|
|
return _encoder.SetPeriodicKeyFrames(enable);
|
|
|
|
|
}
|
|
|
|
|
|
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) {
|
2012-10-24 18:33:04 +00:00
|
|
|
I420VideoFrame image;
|
2012-10-25 11:29:51 +00:00
|
|
|
std::vector<VideoFrameType> video_frame_types(frame_types.size(),
|
|
|
|
|
kDeltaFrame);
|
|
|
|
|
VCMEncodedFrame::ConvertFrameTypes(frame_types, &video_frame_types);
|
2012-10-08 07:06:53 +00:00
|
|
|
return _encoder.Encode(image, NULL, &video_frame_types);
|
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::RegisterEncodeCallback(VCMEncodedFrameCallback* VCMencodedFrameCallback)
|
|
|
|
|
{
|
|
|
|
|
_VCMencodedFrameCallback = VCMencodedFrameCallback;
|
|
|
|
|
_VCMencodedFrameCallback->SetInternalSource(_internalSource);
|
|
|
|
|
return _encoder.RegisterEncodeCompleteCallback(_VCMencodedFrameCallback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
VCMGenericEncoder::InternalSource() const
|
|
|
|
|
{
|
|
|
|
|
return _internalSource;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***************************
|
|
|
|
|
* Callback Implementation
|
|
|
|
|
***************************/
|
2014-01-09 08:01:57 +00:00
|
|
|
VCMEncodedFrameCallback::VCMEncodedFrameCallback(
|
|
|
|
|
EncodedImageCallback* post_encode_callback):
|
2011-07-07 08:21:25 +00:00
|
|
|
_sendCallback(),
|
2012-01-19 12:30:21 +00:00
|
|
|
_mediaOpt(NULL),
|
2011-07-07 08:21:25 +00:00
|
|
|
_payloadType(0),
|
2013-11-26 11:41:59 +00:00
|
|
|
_internalSource(false),
|
2014-01-09 08:01:57 +00:00
|
|
|
post_encode_callback_(post_encode_callback)
|
2012-07-20 11:17:23 +00:00
|
|
|
#ifdef DEBUG_ENCODER_BIT_STREAM
|
|
|
|
|
, _bitStreamAfterEncoder(NULL)
|
|
|
|
|
#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) {
|
|
|
|
|
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;
|
|
|
|
|
RTPVideoHeader* rtpVideoHeaderPtr = &rtpVideoHeader;
|
|
|
|
|
CopyCodecSpecific(codecSpecificInfo, &rtpVideoHeaderPtr);
|
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
|