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 "sdk/objc/native/src/objc_video_decoder_factory.h" 12 13#import "base/RTCMacros.h" 14#import "base/RTCVideoDecoder.h" 15#import "base/RTCVideoDecoderFactory.h" 16#import "base/RTCVideoFrame.h" 17#import "base/RTCVideoFrameBuffer.h" 18#import "components/video_codec/RTCCodecSpecificInfoH264.h" 19#import "sdk/objc/api/peerconnection/RTCEncodedImage+Private.h" 20#import "sdk/objc/api/peerconnection/RTCVideoCodecInfo+Private.h" 21#import "sdk/objc/api/video_codec/RTCWrappedNativeVideoDecoder.h" 22#import "sdk/objc/helpers/NSString+StdString.h" 23 24#include "api/video_codecs/sdp_video_format.h" 25#include "api/video_codecs/video_decoder.h" 26#include "modules/video_coding/include/video_codec_interface.h" 27#include "modules/video_coding/include/video_error_codes.h" 28#include "rtc_base/logging.h" 29#include "rtc_base/time_utils.h" 30#include "sdk/objc/native/src/objc_frame_buffer.h" 31 32namespace webrtc { 33 34namespace { 35class ObjCVideoDecoder : public VideoDecoder { 36 public: 37 ObjCVideoDecoder(id<RTC_OBJC_TYPE(RTCVideoDecoder)> decoder) 38 : decoder_(decoder), implementation_name_([decoder implementationName].stdString) {} 39 40 bool Configure(const Settings &settings) override { 41 return 42 [decoder_ startDecodeWithNumberOfCores:settings.number_of_cores()] == WEBRTC_VIDEO_CODEC_OK; 43 } 44 45 int32_t Decode(const EncodedImage &input_image, 46 bool missing_frames, 47 int64_t render_time_ms = -1) override { 48 RTC_OBJC_TYPE(RTCEncodedImage) *encodedImage = 49 [[RTC_OBJC_TYPE(RTCEncodedImage) alloc] initWithNativeEncodedImage:input_image]; 50 51 return [decoder_ decode:encodedImage 52 missingFrames:missing_frames 53 codecSpecificInfo:nil 54 renderTimeMs:render_time_ms]; 55 } 56 57 int32_t RegisterDecodeCompleteCallback(DecodedImageCallback *callback) override { 58 [decoder_ setCallback:^(RTC_OBJC_TYPE(RTCVideoFrame) * frame) { 59 const auto buffer = rtc::make_ref_counted<ObjCFrameBuffer>(frame.buffer); 60 VideoFrame videoFrame = 61 VideoFrame::Builder() 62 .set_video_frame_buffer(buffer) 63 .set_timestamp_rtp((uint32_t)(frame.timeStampNs / rtc::kNumNanosecsPerMicrosec)) 64 .set_timestamp_ms(0) 65 .set_rotation((VideoRotation)frame.rotation) 66 .build(); 67 videoFrame.set_timestamp(frame.timeStamp); 68 69 callback->Decoded(videoFrame); 70 }]; 71 72 return WEBRTC_VIDEO_CODEC_OK; 73 } 74 75 int32_t Release() override { return [decoder_ releaseDecoder]; } 76 77 const char *ImplementationName() const override { return implementation_name_.c_str(); } 78 79 private: 80 id<RTC_OBJC_TYPE(RTCVideoDecoder)> decoder_; 81 const std::string implementation_name_; 82}; 83} // namespace 84 85ObjCVideoDecoderFactory::ObjCVideoDecoderFactory( 86 id<RTC_OBJC_TYPE(RTCVideoDecoderFactory)> decoder_factory) 87 : decoder_factory_(decoder_factory) {} 88 89ObjCVideoDecoderFactory::~ObjCVideoDecoderFactory() {} 90 91id<RTC_OBJC_TYPE(RTCVideoDecoderFactory)> ObjCVideoDecoderFactory::wrapped_decoder_factory() const { 92 return decoder_factory_; 93} 94 95std::unique_ptr<VideoDecoder> ObjCVideoDecoderFactory::CreateVideoDecoder( 96 const SdpVideoFormat &format) { 97 NSString *codecName = [NSString stringWithUTF8String:format.name.c_str()]; 98 for (RTC_OBJC_TYPE(RTCVideoCodecInfo) * codecInfo in decoder_factory_.supportedCodecs) { 99 if ([codecName isEqualToString:codecInfo.name]) { 100 id<RTC_OBJC_TYPE(RTCVideoDecoder)> decoder = [decoder_factory_ createDecoder:codecInfo]; 101 102 if ([decoder isKindOfClass:[RTC_OBJC_TYPE(RTCWrappedNativeVideoDecoder) class]]) { 103 return [(RTC_OBJC_TYPE(RTCWrappedNativeVideoDecoder) *)decoder releaseWrappedDecoder]; 104 } else { 105 return std::unique_ptr<ObjCVideoDecoder>(new ObjCVideoDecoder(decoder)); 106 } 107 } 108 } 109 110 return nullptr; 111} 112 113std::vector<SdpVideoFormat> ObjCVideoDecoderFactory::GetSupportedFormats() const { 114 std::vector<SdpVideoFormat> supported_formats; 115 for (RTC_OBJC_TYPE(RTCVideoCodecInfo) * supportedCodec in decoder_factory_.supportedCodecs) { 116 SdpVideoFormat format = [supportedCodec nativeSdpVideoFormat]; 117 supported_formats.push_back(format); 118 } 119 120 return supported_formats; 121} 122 123} // namespace webrtc 124