xref: /aosp_15_r20/external/webrtc/sdk/objc/native/src/objc_video_decoder_factory.mm (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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