Skip to content

Commit

Permalink
实时更新fps
Browse files Browse the repository at this point in the history
  • Loading branch information
kingslay committed Oct 14, 2023
1 parent 4a3c63d commit 58838b6
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 35 deletions.
7 changes: 7 additions & 0 deletions Demo/SwiftUI/Shared/Defaults.swift
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,13 @@ public class Defaults: ObservableObject {
}
}

@AppStorage("displayCriteriaFormatDescriptionEnabled")
public var displayCriteriaFormatDescriptionEnabled = KSOptions.displayCriteriaFormatDescriptionEnabled {
didSet {
KSOptions.displayCriteriaFormatDescriptionEnabled = displayCriteriaFormatDescriptionEnabled
}
}

public static let shared = Defaults()
private init() {
KSOptions.isUseAudioRenderer = isUseAudioRenderer
Expand Down
4 changes: 3 additions & 1 deletion Demo/SwiftUI/Shared/SettingView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,14 @@ struct SettingVideoView: View {
private var asynchronousDecompression
@Default(\.isUseDisplayLayer)
private var isUseDisplayLayer

@Default(\.displayCriteriaFormatDescriptionEnabled)
private var displayCriteriaFormatDescriptionEnabled
var body: some View {
Form {
Toggle("Hardware decoder", isOn: $hardwareDecode)
Toggle("Asynchronous Decompression", isOn: $asynchronousDecompression)
Toggle("Use DisplayLayer", isOn: $isUseDisplayLayer)
Toggle("Enable FormatDescription DisplayCriteria ", isOn: $displayCriteriaFormatDescriptionEnabled)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/KSPlayer/MEPlayer/FFmpegDecode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class FFmpegDecode: DecodeProtocol {
codecContext?.pointee.time_base = assetTrack.timebase.rational
filter = MEFilter(timebase: assetTrack.timebase, isAudio: assetTrack.mediaType == .audio, nominalFrameRate: assetTrack.nominalFrameRate, options: options)
if assetTrack.mediaType == .video {
swresample = VideoSwresample()
swresample = VideoSwresample(fps: assetTrack.nominalFrameRate)
} else {
assetTrack.audioDescriptor?.setAudioSession(isUseAudioRenderer: options.isUseAudioRenderer)
swresample = AudioSwresample(audioDescriptor: assetTrack.audioDescriptor!)
Expand Down
12 changes: 3 additions & 9 deletions Sources/KSPlayer/MEPlayer/KSMEPlayer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -177,15 +177,15 @@ extension KSMEPlayer: MEPlayerDelegate {
if vidoeTracks.isEmpty {
videoOutput = nil
}
let fps = vidoeTracks.first { $0.isEnabled }.map(\.nominalFrameRate) ?? 24
let audioDescriptor = tracks(mediaType: .audio).first { $0.isEnabled }.flatMap {
$0 as? FFmpegAssetTrack
}?.audioDescriptor ?? .defaultValue
runInMainqueue { [weak self] in
guard let self else { return }
self.audioOutput.prepare(audioFormat: audioDescriptor.audioFormat)
self.videoOutput?.prepare(fps: fps, startPlayTime: self.options.startPlayTime)
self.videoOutput?.play()
if let controlTimebase = videoOutput?.displayView.displayLayer.controlTimebase, self.options.startPlayTime > 1 {
CMTimebaseSetTime(controlTimebase, time: CMTimeMake(value: Int64(self.options.startPlayTime), timescale: 1))
}
self.delegate?.readyToPlay(player: self)
}
}
Expand Down Expand Up @@ -421,12 +421,6 @@ extension KSMEPlayer: MediaPlayerProtocol {
}

public func select(track: some MediaPlayerTrack) {
if track.mediaType == .video {
let fps = tracks(mediaType: .video).first { $0.isEnabled }.map(\.nominalFrameRate) ?? 24
if fps != track.nominalFrameRate {
videoOutput?.prepare(fps: fps)
}
}
playerItem.select(track: track)
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/KSPlayer/MEPlayer/MEPlayerItemTrack.swift
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ extension SyncPlayerItemTrack {
if mediaType == .video, options.asynchronousDecompression, options.hardwareDecode,
let session = DecompressionSession(assetTrack: assetTrack, options: options)
{
return VideoToolboxDecode(assetTrack: assetTrack, options: options, session: session)
return VideoToolboxDecode(options: options, session: session)
} else {
return FFmpegDecode(assetTrack: assetTrack, options: options)
}
Expand Down
31 changes: 16 additions & 15 deletions Sources/KSPlayer/MEPlayer/MetalPlayView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,21 @@ public final class MetalPlayView: UIView {
}
}

private var fps = Float(60)
private var fps = Float(60) {
didSet {
if fps != oldValue {
let preferredFramesPerSecond = Int(ceil(fps))
displayLink.preferredFramesPerSecond = preferredFramesPerSecond << 1
#if os(iOS)
if #available(iOS 15.0, tvOS 15.0, *) {
displayLink.preferredFrameRateRange = CAFrameRateRange(minimum: Float(preferredFramesPerSecond), maximum: Float(preferredFramesPerSecond << 1))
}
#endif
options.updateVideo(refreshRate: fps, formatDescription: formatDescription)
}
}
}

public private(set) var pixelBuffer: CVPixelBuffer?
/// 用displayLink会导致锁屏无法draw,
/// 用DispatchSourceTimer的话,在播放4k视频的时候repeat的时间会变长,
Expand Down Expand Up @@ -54,20 +68,6 @@ public final class MetalPlayView: UIView {
pause()
}

func prepare(fps: Float, startPlayTime: TimeInterval = 0) {
self.fps = fps
let preferredFramesPerSecond = Int(ceil(fps))
displayLink.preferredFramesPerSecond = preferredFramesPerSecond << 1
#if os(iOS)
if #available(iOS 15.0, tvOS 15.0, *) {
displayLink.preferredFrameRateRange = CAFrameRateRange(minimum: Float(preferredFramesPerSecond), maximum: Float(preferredFramesPerSecond << 1))
}
#endif
if let controlTimebase = displayView.displayLayer.controlTimebase, startPlayTime > 1 {
CMTimebaseSetTime(controlTimebase, time: CMTimeMake(value: Int64(startPlayTime), timescale: 1))
}
}

func play() {
displayLink.isPaused = false
}
Expand Down Expand Up @@ -161,6 +161,7 @@ extension MetalPlayView {
guard let pixelBuffer else {
return
}
fps = frame.fps
let cmtime = frame.cmtime
let par = pixelBuffer.size
let sar = pixelBuffer.aspectRatio
Expand Down
4 changes: 4 additions & 0 deletions Sources/KSPlayer/MEPlayer/Model.swift
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,11 @@ final class VideoVTBFrame: MEFrame {
var duration: Int64 = 0
var position: Int64 = 0
var size: Int32 = 0
let fps: Float
var corePixelBuffer: CVPixelBuffer?
init(fps: Float) {
self.fps = fps
}
}

extension Array {
Expand Down
6 changes: 4 additions & 2 deletions Sources/KSPlayer/MEPlayer/Resample.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ class VideoSwresample: Swresample {
private var width: Int32 = 0
private var pool: CVPixelBufferPool?
private let dstFormat: AVPixelFormat?
init(dstFormat: AVPixelFormat? = nil) {
private let fps: Float
init(dstFormat: AVPixelFormat? = nil, fps: Float = 60) {
self.dstFormat = dstFormat
self.fps = fps
}

func transfer(avframe: UnsafeMutablePointer<AVFrame>) throws -> MEFrame {
let frame = VideoVTBFrame()
let frame = VideoVTBFrame(fps: fps)
if avframe.pointee.format == AV_PIX_FMT_VIDEOTOOLBOX.rawValue {
frame.corePixelBuffer = unsafeBitCast(avframe.pointee.data.3, to: CVPixelBuffer.self)
} else {
Expand Down
10 changes: 4 additions & 6 deletions Sources/KSPlayer/MEPlayer/VideoToolboxDecode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,14 @@ import Libavformat
import VideoToolbox
class VideoToolboxDecode: DecodeProtocol {
private var session: DecompressionSession?
private let timebase: Timebase
private let options: KSOptions
private var startTime = Int64(0)
private var lastPosition = Int64(0)
required convenience init(assetTrack: FFmpegAssetTrack, options: KSOptions) {
self.init(assetTrack: assetTrack, options: options, session: DecompressionSession(assetTrack: assetTrack, options: options))
self.init(options: options, session: DecompressionSession(assetTrack: assetTrack, options: options))
}

init(assetTrack: FFmpegAssetTrack, options: KSOptions, session: DecompressionSession?) {
timebase = assetTrack.timebase
init(options: KSOptions, session: DecompressionSession?) {
self.options = options
self.session = session
}
Expand Down Expand Up @@ -51,9 +49,9 @@ class VideoToolboxDecode: DecodeProtocol {
}
return
}
let frame = VideoVTBFrame()
let frame = VideoVTBFrame(fps: session.assetTrack.nominalFrameRate)
frame.corePixelBuffer = imageBuffer
frame.timebase = self.timebase
frame.timebase = session.assetTrack.timebase
if packetFlags & AV_PKT_FLAG_KEY == 1, packetFlags & AV_PKT_FLAG_DISCARD != 0, self.lastPosition > 0 {
self.startTime = self.lastPosition - pts
}
Expand Down

0 comments on commit 58838b6

Please sign in to comment.