OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright 2017 The WebRTC project authors. All Rights Reserved. |
| 3 * |
| 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. |
| 9 */ |
| 10 |
| 11 #include "webrtc/sdk/objc/Framework/Classes/VideoToolbox/objc_video_encoder_fact
ory.h" |
| 12 |
| 13 #import "RTCVideoCodec+Private.h" |
| 14 #import "WebRTC/RTCVideoCodec.h" |
| 15 #import "WebRTC/RTCVideoCodecFactory.h" |
| 16 #import "WebRTC/RTCVideoCodecH264.h" |
| 17 #import "WebRTC/RTCVideoFrame.h" |
| 18 #import "WebRTC/RTCVideoFrameBuffer.h" |
| 19 |
| 20 #include "webrtc/api/video/video_frame.h" |
| 21 #include "webrtc/api/video_codecs/video_encoder.h" |
| 22 #include "webrtc/modules/include/module_common_types.h" |
| 23 #include "webrtc/modules/video_coding/include/video_codec_interface.h" |
| 24 #include "webrtc/modules/video_coding/include/video_error_codes.h" |
| 25 #include "webrtc/rtc_base/logging.h" |
| 26 #include "webrtc/rtc_base/timeutils.h" |
| 27 #include "webrtc/sdk/objc/Framework/Classes/Common/helpers.h" |
| 28 #include "webrtc/sdk/objc/Framework/Classes/Video/objc_frame_buffer.h" |
| 29 |
| 30 namespace webrtc { |
| 31 |
| 32 namespace { |
| 33 class ObjCVideoEncoder : public VideoEncoder { |
| 34 public: |
| 35 ObjCVideoEncoder(id<RTCVideoEncoder> encoder) : encoder_(encoder) {} |
| 36 ~ObjCVideoEncoder() { [encoder_ destroy]; } |
| 37 |
| 38 int32_t InitEncode(const VideoCodec *codec_settings, |
| 39 int32_t number_of_cores, |
| 40 size_t max_payload_size) { |
| 41 RTCVideoEncoderSettings *settings = |
| 42 [[RTCVideoEncoderSettings alloc] initWithVideoCodec:codec_settings]; |
| 43 return [encoder_ startEncodeWithSettings:settings numberOfCores:number_of_co
res]; |
| 44 } |
| 45 |
| 46 int32_t RegisterEncodeCompleteCallback(EncodedImageCallback *callback) { |
| 47 [encoder_ setCallback:^(RTCEncodedImage *frame, |
| 48 id<RTCCodecSpecificInfo> info, |
| 49 RTCRtpFragmentationHeader *header) { |
| 50 EncodedImage encodedImage = [frame toCpp]; |
| 51 |
| 52 // Handle types than can be converted into one of webrtc::CodecSpecificInf
o's hard coded |
| 53 // cases. |
| 54 CodecSpecificInfo codecSpecificInfo; |
| 55 if ([info isKindOfClass:[RTCCodecSpecificInfoH264 class]]) { |
| 56 codecSpecificInfo = [(RTCCodecSpecificInfoH264 *)info toCpp]; |
| 57 } |
| 58 |
| 59 std::unique_ptr<webrtc::RTPFragmentationHeader> fragmentationHeader = [hea
der toCpp]; |
| 60 callback->OnEncodedImage(encodedImage, &codecSpecificInfo, fragmentationHe
ader.release()); |
| 61 }]; |
| 62 |
| 63 return WEBRTC_VIDEO_CODEC_OK; |
| 64 } |
| 65 |
| 66 int32_t Release() { return [encoder_ releaseEncoder]; } |
| 67 |
| 68 int32_t Encode(const VideoFrame &frame, |
| 69 const CodecSpecificInfo *codec_specific_info, |
| 70 const std::vector<FrameType> *frame_types) { |
| 71 RTC_CHECK(frame.video_frame_buffer()->type() == VideoFrameBuffer::Type::kNat
ive); |
| 72 |
| 73 id<RTCVideoFrameBuffer> frame_buffer = |
| 74 static_cast<ObjCFrameBuffer *>(frame.video_frame_buffer().get())->wrappe
d_frame_buffer(); |
| 75 RTCVideoFrame *rtcFrame = |
| 76 [[RTCVideoFrame alloc] initWithBuffer:frame_buffer |
| 77 rotation:RTCVideoRotation(frame.rotation()) |
| 78 timeStampNs:frame.timestamp_us() * rtc::kNumNa
nosecsPerMicrosec]; |
| 79 rtcFrame.timeStamp = frame.timestamp(); |
| 80 |
| 81 // webrtc::CodecSpecificInfo only handles a hard coded list of codecs |
| 82 id<RTCCodecSpecificInfo> rtcCodecSpecificInfo = nil; |
| 83 if (codec_specific_info) { |
| 84 if (strcmp(codec_specific_info->codec_name, "H264") == 0) { |
| 85 RTCCodecSpecificInfoH264 *h264Info = [[RTCCodecSpecificInfoH264 alloc] i
nit]; |
| 86 h264Info.packetizationMode = |
| 87 (RTCH264PacketizationMode)codec_specific_info->codecSpecific.H264.pa
cketization_mode; |
| 88 rtcCodecSpecificInfo = h264Info; |
| 89 } |
| 90 } |
| 91 |
| 92 NSMutableArray<NSNumber *> *rtcFrameTypes = [NSMutableArray array]; |
| 93 for (size_t i = 0; i < frame_types->size(); ++i) { |
| 94 [rtcFrameTypes addObject:@(RTCFrameType(frame_types->at(i)))]; |
| 95 } |
| 96 |
| 97 return |
| 98 [encoder_ encode:rtcFrame codecSpecificInfo:rtcCodecSpecificInfo frameTy
pes:rtcFrameTypes]; |
| 99 } |
| 100 |
| 101 int32_t SetChannelParameters(uint32_t packet_loss, int64_t rtt) { return WEBRT
C_VIDEO_CODEC_OK; } |
| 102 |
| 103 int32_t SetRates(uint32_t bitrate, uint32_t framerate) { |
| 104 if ([encoder_ setBitrate:bitrate framerate:framerate]) { |
| 105 return WEBRTC_VIDEO_CODEC_OK; |
| 106 } else { |
| 107 return WEBRTC_VIDEO_CODEC_ERROR; |
| 108 } |
| 109 } |
| 110 |
| 111 bool SupportsNativeHandle() const { return true; } |
| 112 |
| 113 private: |
| 114 id<RTCVideoEncoder> encoder_; |
| 115 }; |
| 116 } // namespace |
| 117 |
| 118 ObjCVideoEncoderFactory::ObjCVideoEncoderFactory(id<RTCVideoEncoderFactory> enco
der_factory) |
| 119 : encoder_factory_(encoder_factory) {} |
| 120 |
| 121 ObjCVideoEncoderFactory::~ObjCVideoEncoderFactory() {} |
| 122 |
| 123 id<RTCVideoEncoderFactory> ObjCVideoEncoderFactory::wrapped_encoder_factory() co
nst { |
| 124 return encoder_factory_; |
| 125 } |
| 126 |
| 127 webrtc::VideoEncoder *ObjCVideoEncoderFactory::CreateVideoEncoder( |
| 128 const cricket::VideoCodec &codec) { |
| 129 RTCVideoCodecInfo *info = [[RTCVideoCodecInfo alloc] initWithVideoCodec:codec]
; |
| 130 id<RTCVideoEncoder> encoder = [encoder_factory_ createEncoder:info]; |
| 131 return new ObjCVideoEncoder(encoder); |
| 132 } |
| 133 |
| 134 const std::vector<cricket::VideoCodec> &ObjCVideoEncoderFactory::supported_codec
s() const { |
| 135 supported_codecs_.clear(); |
| 136 for (RTCVideoCodecInfo *supportedCodec in encoder_factory_.supportedCodecs) { |
| 137 cricket::VideoCodec codec = [supportedCodec toCpp]; |
| 138 supported_codecs_.push_back(codec); |
| 139 } |
| 140 |
| 141 return supported_codecs_; |
| 142 } |
| 143 |
| 144 void ObjCVideoEncoderFactory::DestroyVideoEncoder(webrtc::VideoEncoder *encoder)
{ |
| 145 delete encoder; |
| 146 encoder = nullptr; |
| 147 } |
| 148 |
| 149 } // namespace webrtc |
OLD | NEW |