From 512bee3dee4afd960e378f951570984e171782b3 Mon Sep 17 00:00:00 2001 From: magjed Date: Fri, 4 Aug 2017 02:05:32 -0700 Subject: [PATCH] ObjC: Support non-native frames in encoder Frames might be non-native, i.e. normal I420 frames, and we should handle that in the encoder. BUG=webrtc:7785,webrtc:7924 Review-Url: https://codereview.webrtc.org/2992943002 Cr-Commit-Position: refs/heads/master@{#19245} --- .../objc_video_encoder_factory.mm | 44 +++++++++++-------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/webrtc/sdk/objc/Framework/Classes/VideoToolbox/objc_video_encoder_factory.mm b/webrtc/sdk/objc/Framework/Classes/VideoToolbox/objc_video_encoder_factory.mm index ecdc716d85..9c507fc9d1 100644 --- a/webrtc/sdk/objc/Framework/Classes/VideoToolbox/objc_video_encoder_factory.mm +++ b/webrtc/sdk/objc/Framework/Classes/VideoToolbox/objc_video_encoder_factory.mm @@ -13,6 +13,7 @@ #include #import "NSString+StdString.h" +#import "RTCI420Buffer+Private.h" #import "RTCVideoCodec+Private.h" #import "WebRTC/RTCVideoCodec.h" #import "WebRTC/RTCVideoCodecFactory.h" @@ -33,6 +34,22 @@ namespace webrtc { namespace { + +id nativeToRtcFrameBuffer(const rtc::scoped_refptr &buffer) { + return buffer->type() == VideoFrameBuffer::Type::kNative ? + static_cast(buffer.get())->wrapped_frame_buffer() : + [[RTCI420Buffer alloc] initWithFrameBuffer:buffer->ToI420()]; +} + +RTCVideoFrame *nativeToRtcFrame(const VideoFrame &frame) { + RTCVideoFrame *rtcFrame = + [[RTCVideoFrame alloc] initWithBuffer:nativeToRtcFrameBuffer(frame.video_frame_buffer()) + rotation:RTCVideoRotation(frame.rotation()) + timeStampNs:frame.timestamp_us() * rtc::kNumNanosecsPerMicrosec]; + rtcFrame.timeStamp = frame.timestamp(); + return rtcFrame; +} + class ObjCVideoEncoder : public VideoEncoder { public: ObjCVideoEncoder(id encoder) @@ -53,14 +70,13 @@ class ObjCVideoEncoder : public VideoEncoder { RTCRtpFragmentationHeader *header) { EncodedImage encodedImage = [frame nativeEncodedImage]; - // Handle types than can be converted into one of webrtc::CodecSpecificInfo's hard coded - // cases. + // Handle types than can be converted into one of CodecSpecificInfo's hard coded cases. CodecSpecificInfo codecSpecificInfo; if ([info isKindOfClass:[RTCCodecSpecificInfoH264 class]]) { codecSpecificInfo = [(RTCCodecSpecificInfoH264 *)info nativeCodecSpecificInfo]; } - std::unique_ptr fragmentationHeader = + std::unique_ptr fragmentationHeader = [header createNativeFragmentationHeader]; callback->OnEncodedImage(encodedImage, &codecSpecificInfo, fragmentationHeader.release()); }]; @@ -73,17 +89,7 @@ class ObjCVideoEncoder : public VideoEncoder { int32_t Encode(const VideoFrame &frame, const CodecSpecificInfo *codec_specific_info, const std::vector *frame_types) { - RTC_CHECK(frame.video_frame_buffer()->type() == VideoFrameBuffer::Type::kNative); - - id frame_buffer = - static_cast(frame.video_frame_buffer().get())->wrapped_frame_buffer(); - RTCVideoFrame *rtcFrame = - [[RTCVideoFrame alloc] initWithBuffer:frame_buffer - rotation:RTCVideoRotation(frame.rotation()) - timeStampNs:frame.timestamp_us() * rtc::kNumNanosecsPerMicrosec]; - rtcFrame.timeStamp = frame.timestamp(); - - // webrtc::CodecSpecificInfo only handles a hard coded list of codecs + // CodecSpecificInfo only handles a hard coded list of codecs id rtcCodecSpecificInfo = nil; if (codec_specific_info) { if (strcmp(codec_specific_info->codec_name, "H264") == 0) { @@ -99,8 +105,9 @@ class ObjCVideoEncoder : public VideoEncoder { [rtcFrameTypes addObject:@(RTCFrameType(frame_types->at(i)))]; } - return - [encoder_ encode:rtcFrame codecSpecificInfo:rtcCodecSpecificInfo frameTypes:rtcFrameTypes]; + return [encoder_ encode:nativeToRtcFrame(frame) + codecSpecificInfo:rtcCodecSpecificInfo + frameTypes:rtcFrameTypes]; } int32_t SetChannelParameters(uint32_t packet_loss, int64_t rtt) { return WEBRTC_VIDEO_CODEC_OK; } @@ -139,8 +146,7 @@ id ObjCVideoEncoderFactory::wrapped_encoder_factory() co return encoder_factory_; } -webrtc::VideoEncoder *ObjCVideoEncoderFactory::CreateVideoEncoder( - const cricket::VideoCodec &codec) { +VideoEncoder *ObjCVideoEncoderFactory::CreateVideoEncoder(const cricket::VideoCodec &codec) { RTCVideoCodecInfo *info = [[RTCVideoCodecInfo alloc] initWithNativeVideoCodec:codec]; id encoder = [encoder_factory_ createEncoder:info]; return new ObjCVideoEncoder(encoder); @@ -156,7 +162,7 @@ const std::vector &ObjCVideoEncoderFactory::supported_codec return supported_codecs_; } -void ObjCVideoEncoderFactory::DestroyVideoEncoder(webrtc::VideoEncoder *encoder) { +void ObjCVideoEncoderFactory::DestroyVideoEncoder(VideoEncoder *encoder) { delete encoder; encoder = nullptr; }