2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
11 #include "webrtc/engine_configurations.h"
12 #include "webrtc/modules/video_coding/main/source/encoded_frame.h"
13 #include "webrtc/modules/video_coding/main/source/generic_encoder.h"
14 #include "webrtc/modules/video_coding/main/source/media_optimization.h"
15 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
16 #include "webrtc/system_wrappers/interface/logging.h"
20 // Map information from info into rtp. If no relevant information is found
21 // in info, rtp is set to NULL.
22 void CopyCodecSpecific(const CodecSpecificInfo* info, RTPVideoHeader** rtp) {
27 switch (info->codecType) {
28 case kVideoCodecVP8: {
29 (*rtp)->codec = kRtpVideoVp8;
30 (*rtp)->codecHeader.VP8.InitRTPVideoHeaderVP8();
31 (*rtp)->codecHeader.VP8.pictureId = info->codecSpecific.VP8.pictureId;
32 (*rtp)->codecHeader.VP8.nonReference =
33 info->codecSpecific.VP8.nonReference;
34 (*rtp)->codecHeader.VP8.temporalIdx = info->codecSpecific.VP8.temporalIdx;
35 (*rtp)->codecHeader.VP8.layerSync = info->codecSpecific.VP8.layerSync;
36 (*rtp)->codecHeader.VP8.tl0PicIdx = info->codecSpecific.VP8.tl0PicIdx;
37 (*rtp)->codecHeader.VP8.keyIdx = info->codecSpecific.VP8.keyIdx;
38 (*rtp)->simulcastIdx = info->codecSpecific.VP8.simulcastIdx;
41 case kVideoCodecGeneric:
42 (*rtp)->codec = kRtpVideoGeneric;
43 (*rtp)->simulcastIdx = info->codecSpecific.generic.simulcast_idx;
46 // No codec specific info. Change RTP header pointer to NULL.
53 //#define DEBUG_ENCODER_BIT_STREAM
55 VCMGenericEncoder::VCMGenericEncoder(VideoEncoder& encoder, bool internalSource /*= false*/)
58 _codecType(kVideoCodecUnknown),
59 _VCMencodedFrameCallback(NULL),
62 _internalSource(internalSource)
67 VCMGenericEncoder::~VCMGenericEncoder()
71 int32_t VCMGenericEncoder::Release()
75 _VCMencodedFrameCallback = NULL;
76 return _encoder.Release();
80 VCMGenericEncoder::InitEncode(const VideoCodec* settings,
81 int32_t numberOfCores,
82 uint32_t maxPayloadSize)
84 _bitRate = settings->startBitrate * 1000;
85 _frameRate = settings->maxFramerate;
86 _codecType = settings->codecType;
87 if (_encoder.InitEncode(settings, numberOfCores, maxPayloadSize) != 0) {
88 LOG(LS_ERROR) << "Failed to initialize the encoder associated with "
89 "payload name: " << settings->plName;
96 VCMGenericEncoder::Encode(const I420VideoFrame& inputFrame,
97 const CodecSpecificInfo* codecSpecificInfo,
98 const std::vector<FrameType>& frameTypes) {
99 std::vector<VideoFrameType> video_frame_types(frameTypes.size(),
101 VCMEncodedFrame::ConvertFrameTypes(frameTypes, &video_frame_types);
102 return _encoder.Encode(inputFrame, codecSpecificInfo, &video_frame_types);
106 VCMGenericEncoder::SetChannelParameters(int32_t packetLoss, int rtt)
108 return _encoder.SetChannelParameters(packetLoss, rtt);
112 VCMGenericEncoder::SetRates(uint32_t newBitRate, uint32_t frameRate)
114 uint32_t target_bitrate_kbps = (newBitRate + 500) / 1000;
115 int32_t ret = _encoder.SetRates(target_bitrate_kbps, frameRate);
120 _bitRate = newBitRate;
121 _frameRate = frameRate;
126 VCMGenericEncoder::CodecConfigParameters(uint8_t* buffer, int32_t size)
128 int32_t ret = _encoder.CodecConfigParameters(buffer, size);
136 uint32_t VCMGenericEncoder::BitRate() const
141 uint32_t VCMGenericEncoder::FrameRate() const
147 VCMGenericEncoder::SetPeriodicKeyFrames(bool enable)
149 return _encoder.SetPeriodicKeyFrames(enable);
152 int32_t VCMGenericEncoder::RequestFrame(
153 const std::vector<FrameType>& frame_types) {
154 I420VideoFrame image;
155 std::vector<VideoFrameType> video_frame_types(frame_types.size(),
157 VCMEncodedFrame::ConvertFrameTypes(frame_types, &video_frame_types);
158 return _encoder.Encode(image, NULL, &video_frame_types);
162 VCMGenericEncoder::RegisterEncodeCallback(VCMEncodedFrameCallback* VCMencodedFrameCallback)
164 _VCMencodedFrameCallback = VCMencodedFrameCallback;
165 _VCMencodedFrameCallback->SetInternalSource(_internalSource);
166 return _encoder.RegisterEncodeCompleteCallback(_VCMencodedFrameCallback);
170 VCMGenericEncoder::InternalSource() const
172 return _internalSource;
175 /***************************
176 * Callback Implementation
177 ***************************/
178 VCMEncodedFrameCallback::VCMEncodedFrameCallback(
179 EncodedImageCallback* post_encode_callback):
183 _internalSource(false),
184 post_encode_callback_(post_encode_callback)
185 #ifdef DEBUG_ENCODER_BIT_STREAM
186 , _bitStreamAfterEncoder(NULL)
189 #ifdef DEBUG_ENCODER_BIT_STREAM
190 _bitStreamAfterEncoder = fopen("encoderBitStream.bit", "wb");
194 VCMEncodedFrameCallback::~VCMEncodedFrameCallback()
196 #ifdef DEBUG_ENCODER_BIT_STREAM
197 fclose(_bitStreamAfterEncoder);
202 VCMEncodedFrameCallback::SetTransportCallback(VCMPacketizationCallback* transport)
204 _sendCallback = transport;
209 VCMEncodedFrameCallback::Encoded(
210 EncodedImage &encodedImage,
211 const CodecSpecificInfo* codecSpecificInfo,
212 const RTPFragmentationHeader* fragmentationHeader)
214 post_encode_callback_->Encoded(encodedImage);
216 FrameType frameType = VCMEncodedFrame::ConvertFrameType(encodedImage._frameType);
218 uint32_t encodedBytes = 0;
219 if (_sendCallback != NULL)
221 encodedBytes = encodedImage._length;
223 #ifdef DEBUG_ENCODER_BIT_STREAM
224 if (_bitStreamAfterEncoder != NULL)
226 fwrite(encodedImage._buffer, 1, encodedImage._length, _bitStreamAfterEncoder);
230 RTPVideoHeader rtpVideoHeader;
231 RTPVideoHeader* rtpVideoHeaderPtr = &rtpVideoHeader;
232 CopyCodecSpecific(codecSpecificInfo, &rtpVideoHeaderPtr);
234 int32_t callbackReturn = _sendCallback->SendData(
237 encodedImage._timeStamp,
238 encodedImage.capture_time_ms_,
239 encodedImage._buffer,
241 *fragmentationHeader,
243 if (callbackReturn < 0)
245 return callbackReturn;
250 return VCM_UNINITIALIZED;
252 if (_mediaOpt != NULL) {
253 _mediaOpt->UpdateWithEncodedData(encodedBytes, encodedImage._timeStamp,
257 return _mediaOpt->DropFrame(); // Signal to encoder to drop next frame
264 VCMEncodedFrameCallback::SetMediaOpt(
265 media_optimization::MediaOptimization *mediaOpt)
267 _mediaOpt = mediaOpt;
270 } // namespace webrtc