Various improvements

This commit is contained in:
Ilya Laktyushin
2025-11-05 20:25:07 +04:00
parent 16cd9b3c29
commit bda836f032
5 changed files with 77 additions and 34 deletions

View File

@@ -103,7 +103,7 @@ final class CameraDeviceContext {
} }
switch DeviceModel.current { switch DeviceModel.current {
case .iPhone15ProMax, .iPhone14ProMax, .iPhone13ProMax, .iPhone16ProMax, .iPhone17Pro, .iPhone17ProMax: case .iPhone15ProMax, .iPhone14ProMax, .iPhone13ProMax, .iPhone16ProMax, .iPhone17Pro, .iPhone17ProMax:
return 60.0 return 30.0
default: default:
return 30.0 return 30.0
} }

View File

@@ -1124,26 +1124,53 @@ private final class CameraScreenComponent: CombinedComponent {
guard let controller = self.getController() else { guard let controller = self.getController() else {
return return
} }
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
let alertController = textAlertController(
context: self.context,
forceTheme: defaultDarkColorPresentationTheme,
title: "End Live Stream",
text: "Are you sure you want to end this live stream?",
actions: [
TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Cancel, action: {}),
TextAlertAction(type: .genericAction, title: "End", action: { [weak self, weak controller] in
guard let self, let controller else {
return
}
let _ = self.liveStreamCall?.leave(terminateIfPossible: true).startStandalone() if case let .liveStream(livestream) = self.liveStreamStory?.media, livestream.kind == .rtmp {
controller.dismiss(animated: true) let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
}) let alertController = textAlertController(
] context: self.context,
) forceTheme: defaultDarkColorPresentationTheme,
controller.present(alertController, in: .window(.root)) title: "End Live Stream",
text: "Are you sure you want to end this live stream?",
actions: [
TextAlertAction(type: .destructiveAction, title: "End", action: { [weak self, weak controller] in
guard let self, let controller else {
return
}
let _ = self.liveStreamCall?.leave(terminateIfPossible: true).startStandalone()
controller.dismiss(animated: true)
}),
TextAlertAction(type: .genericAction, title: "Leave", action: { [weak controller] in
guard let controller else {
return
}
controller.dismiss(animated: true)
}),
TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Cancel, action: {})
],
actionLayout: .vertical
)
controller.present(alertController, in: .window(.root))
} else {
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
let alertController = textAlertController(
context: self.context,
forceTheme: defaultDarkColorPresentationTheme,
title: "End Live Stream",
text: "Are you sure you want to end this live stream?",
actions: [
TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Cancel, action: {}),
TextAlertAction(type: .destructiveAction, title: "End", action: { [weak self, weak controller] in
guard let self, let controller else {
return
}
let _ = self.liveStreamCall?.leave(terminateIfPossible: true).startStandalone()
controller.dismiss(animated: true)
})
]
)
controller.present(alertController, in: .window(.root))
}
} }
func setupLiveStreamCamera(call: PresentationGroupCall) { func setupLiveStreamCamera(call: PresentationGroupCall) {
@@ -1913,11 +1940,11 @@ private final class CameraScreenComponent: CombinedComponent {
} }
let availableModes: [CameraMode] let availableModes: [CameraMode]
#if DEBUG //#if DEBUG
availableModes = [.photo, .video, .live] availableModes = [.photo, .video, .live]
#else //#else
availableModes = [.photo, .video] //availableModes = [.photo, .video]
#endif //#endif
let modeControl = modeControl.update( let modeControl = modeControl.update(
component: ModeComponent( component: ModeComponent(

View File

@@ -110,7 +110,8 @@ final class LiveStreamMediaSource {
kCVPixelBufferPoolMinimumBufferCountKey as String: 3 as NSNumber kCVPixelBufferPoolMinimumBufferCountKey as String: 3 as NSNumber
] ]
let pixelBufferOptions: [String: Any] = [ let pixelBufferOptions: [String: Any] = [
kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA as NSNumber, //kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA as NSNumber,
kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange as NSNumber,
kCVPixelBufferWidthKey as String: UInt32(width), kCVPixelBufferWidthKey as String: UInt32(width),
kCVPixelBufferHeightKey as String: UInt32(height) kCVPixelBufferHeightKey as String: UInt32(height)
] ]
@@ -168,7 +169,8 @@ final class LiveStreamMediaSource {
outputDimensions: CGSize(width: 720.0, height: 1280.0), outputDimensions: CGSize(width: 720.0, height: 1280.0),
textScale: 1.0, textScale: 1.0,
videoDuration: nil, videoDuration: nil,
additionalVideoDuration: nil additionalVideoDuration: nil,
outputsYuvBuffers: true
) )
self.mainVideoOutput = CameraVideoOutput(sink: { [weak self] buffer, mirror in self.mainVideoOutput = CameraVideoOutput(sink: { [weak self] buffer, mirror in

View File

@@ -97,6 +97,9 @@ public final class MediaEditorComposer {
private let outputDimensions: CGSize private let outputDimensions: CGSize
private let textScale: CGFloat private let textScale: CGFloat
private let outputsYuvBuffers: Bool
private let yuvPixelFormat: OSType = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange
private let renderer = MediaEditorRenderer() private let renderer = MediaEditorRenderer()
private let renderChain = MediaEditorRenderChain() private let renderChain = MediaEditorRenderChain()
@@ -112,12 +115,14 @@ public final class MediaEditorComposer {
outputDimensions: CGSize, outputDimensions: CGSize,
textScale: CGFloat, textScale: CGFloat,
videoDuration: Double?, videoDuration: Double?,
additionalVideoDuration: Double? additionalVideoDuration: Double?,
outputsYuvBuffers: Bool = false
) { ) {
self.values = values self.values = values
self.dimensions = dimensions self.dimensions = dimensions
self.outputDimensions = outputDimensions self.outputDimensions = outputDimensions
self.textScale = textScale self.textScale = textScale
self.outputsYuvBuffers = outputsYuvBuffers
let colorSpace = CGColorSpaceCreateDeviceRGB() let colorSpace = CGColorSpaceCreateDeviceRGB()
self.colorSpace = colorSpace self.colorSpace = colorSpace
@@ -161,7 +166,7 @@ public final class MediaEditorComposer {
self.renderChain.update(values: self.values) self.renderChain.update(values: self.values)
self.renderer.videoFinishPass.update(values: self.values, videoDuration: videoDuration, additionalVideoDuration: additionalVideoDuration) self.renderer.videoFinishPass.update(values: self.values, videoDuration: videoDuration, additionalVideoDuration: additionalVideoDuration)
} }
var previousAdditionalInput: [Int: Input] = [:] var previousAdditionalInput: [Int: Input] = [:]
public func process(main: Input, additional: [Input?], timestamp: CMTime, pool: CVPixelBufferPool?, completion: @escaping (CVPixelBuffer?) -> Void) { public func process(main: Input, additional: [Input?], timestamp: CMTime, pool: CVPixelBufferPool?, completion: @escaping (CVPixelBuffer?) -> Void) {
guard let pool, let ciContext = self.ciContext else { guard let pool, let ciContext = self.ciContext else {
@@ -185,26 +190,35 @@ public final class MediaEditorComposer {
if let resultTexture = self.renderer.resultTexture, var ciImage = CIImage(mtlTexture: resultTexture, options: [.colorSpace: self.colorSpace]) { if let resultTexture = self.renderer.resultTexture, var ciImage = CIImage(mtlTexture: resultTexture, options: [.colorSpace: self.colorSpace]) {
ciImage = ciImage.transformed(by: CGAffineTransformMakeScale(1.0, -1.0).translatedBy(x: 0.0, y: -ciImage.extent.height)) ciImage = ciImage.transformed(by: CGAffineTransformMakeScale(1.0, -1.0).translatedBy(x: 0.0, y: -ciImage.extent.height))
var pixelBuffer: CVPixelBuffer? var pixelBuffer: CVPixelBuffer?
CVPixelBufferPoolCreatePixelBuffer(kCFAllocatorDefault, pool, &pixelBuffer) CVPixelBufferPoolCreatePixelBuffer(kCFAllocatorDefault, pool, &pixelBuffer)
if let pixelBuffer { guard let pixelBuffer else {
completion(nil)
return
}
if self.outputsYuvBuffers {
let scale = self.outputDimensions.width / ciImage.extent.width
ciImage = ciImage.samplingLinear().transformed(by: CGAffineTransform(scaleX: scale, y: scale))
ciContext.render(ciImage, to: pixelBuffer)
completion(pixelBuffer)
} else {
makeEditorImageFrameComposition(context: ciContext, inputImage: ciImage, drawingImage: self.drawingImage, maskImage: self.maskImage, dimensions: self.dimensions, values: self.values, entities: self.entities, time: timestamp, completion: { compositedImage in makeEditorImageFrameComposition(context: ciContext, inputImage: ciImage, drawingImage: self.drawingImage, maskImage: self.maskImage, dimensions: self.dimensions, values: self.values, entities: self.entities, time: timestamp, completion: { compositedImage in
if var compositedImage { if var compositedImage {
let scale = self.outputDimensions.width / compositedImage.extent.width let scale = self.outputDimensions.width / compositedImage.extent.width
compositedImage = compositedImage.samplingLinear().transformed(by: CGAffineTransform(scaleX: scale, y: scale)) compositedImage = compositedImage.samplingLinear().transformed(by: CGAffineTransform(scaleX: scale, y: scale))
self.ciContext?.render(compositedImage, to: pixelBuffer) ciContext.render(compositedImage, to: pixelBuffer)
completion(pixelBuffer) completion(pixelBuffer)
} else { } else {
completion(nil) completion(nil)
} }
}) })
return
} }
} }
completion(nil)
} }
private var cachedTextures: [Int: MTLTexture] = [:] private var cachedTextures: [Int: MTLTexture] = [:]

View File

@@ -1032,7 +1032,7 @@ public final class MessageInputPanelComponent: Component {
strings: component.strings, strings: component.strings,
chatPeerId: component.chatLocation?.peerId ?? component.context.account.peerId, chatPeerId: component.chatLocation?.peerId ?? component.context.account.peerId,
inlineActions: inlineActions, inlineActions: inlineActions,
leftAction: ChatTextInputPanelComponent.LeftAction(kind: .toggleExpanded(isVisible: component.liveChatState?.isEnabled == true, isExpanded: component.liveChatState?.isExpanded ?? true && component.liveChatState?.isEmpty == false, hasUnseen: component.liveChatState?.hasUnseenMessages ?? false), action: { [weak self] in leftAction: ChatTextInputPanelComponent.LeftAction(kind: .toggleExpanded(isVisible: component.liveChatState?.isEnabled == true, isExpanded: component.liveChatState?.isExpanded ?? true && component.liveChatState?.isEmpty == false, hasUnseen: component.liveChatState?.hasUnseenMessages ?? false), action: { [weak self] in
guard let self, let component = self.component else { guard let self, let component = self.component else {
return return
} }